authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-07 17:07:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-07 17:07:18-05:00
log3e08b3a4f89ee8e6102fcc67fc7e77c5e3eba104
treee45ce5ccef05c44a202de42901bb3513ac0b178b
parent91baa574a5f7224b48e4499a9db0c5283d800ec3
signaturelock-open Commit is signed but in an unrecognized format.

update embedded LLD to 8.0.0rc2


713 files changed, 20169 insertions(+), 5796 deletions(-)

CMakeLists.txt+4-1
...@@ -113,6 +113,7 @@ else()...@@ -113,6 +113,7 @@ else()
113 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp"113 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp"
114 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp"114 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp"
115 )115 )
116
116 set(EMBEDDED_LLD_ELF_SOURCES117 set(EMBEDDED_LLD_ELF_SOURCES
117 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/AArch64ErrataFix.cpp"118 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/AArch64ErrataFix.cpp"
118 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp"119 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp"
...@@ -120,19 +121,21 @@ else()...@@ -120,19 +121,21 @@ else()
120 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/ARM.cpp"121 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/ARM.cpp"
121 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AVR.cpp"122 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AVR.cpp"
122 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Hexagon.cpp"123 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Hexagon.cpp"
124 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MSP430.cpp"
123 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Mips.cpp"125 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Mips.cpp"
124 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MipsArchTree.cpp"126 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MipsArchTree.cpp"
125 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp"127 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp"
126 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp"128 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp"
129 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/RISCV.cpp"
127 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp"130 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp"
128 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86.cpp"131 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86.cpp"
129 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp"132 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp"
130 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/CallGraphSort.cpp"133 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/CallGraphSort.cpp"
134 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DWARF.cpp"
131 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp"135 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp"
132 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp"136 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp"
133 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp"137 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp"
134 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp"138 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp"
135 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/GdbIndex.cpp"
136 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp"139 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp"
137 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp"140 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp"
138 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputSection.cpp"141 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputSection.cpp"
deps/lld-prebuilt/COFF/Options.inc+17-14
...@@ -55,10 +55,8 @@ OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, IN...@@ -55,10 +55,8 @@ OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, IN
55 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)55 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)
56OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,56OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
57 "Use colors in diagnostics", nullptr, nullptr)57 "Use colors in diagnostics", nullptr, nullptr)
58OPTION(prefix_1, "debug:dwarf", debug_dwarf, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)58OPTION(prefix_1, "debug:", debug_opt, Joined, INVALID, INVALID, nullptr, 0, 0,
59OPTION(prefix_1, "debug:full", debug_full, Flag, INVALID, debug, nullptr, 0, 0, nullptr, nullptr, nullptr)59 "Embed a symbol table in the image with option", nullptr, nullptr)
60OPTION(prefix_1, "debug:ghash", debug_ghash, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
61OPTION(prefix_1, "debug:symtab", debug_symtab, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
62OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0,60OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0,
63 "Debug Info Options", nullptr, nullptr)61 "Debug Info Options", nullptr, nullptr)
64OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0,62OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -95,9 +93,12 @@ OPTION(prefix_1, "fixed:no", fixed_no, Flag, INVALID, INVALID, nullptr, 0, 0,...@@ -95,9 +93,12 @@ OPTION(prefix_1, "fixed:no", fixed_no, Flag, INVALID, INVALID, nullptr, 0, 0,
95 "Enable base relocations (default)", nullptr, nullptr)93 "Enable base relocations (default)", nullptr, nullptr)
96OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0,94OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0,
97 "Disable base relocations", nullptr, nullptr)95 "Disable base relocations", nullptr, nullptr)
98OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)96OPTION(prefix_1, "force:multiple", force_multiple, Flag, INVALID, INVALID, nullptr, 0, 0,
99OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0,97 "Allow multiply defined symbols when creating executables", nullptr, nullptr)
98OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0,
100 "Allow undefined symbols when creating executables", nullptr, nullptr)99 "Allow undefined symbols when creating executables", nullptr, nullptr)
100OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0,
101 "Allow undefined and multiply defined symbols when creating executables", nullptr, nullptr)
101OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)102OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
102OPTION(prefix_1, "guard:", guard, Joined, INVALID, INVALID, nullptr, 0, 0,103OPTION(prefix_1, "guard:", guard, Joined, INVALID, INVALID, nullptr, 0, 0,
103 "Control flow guard", nullptr, nullptr)104 "Control flow guard", nullptr, nullptr)
...@@ -148,30 +149,32 @@ OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr,...@@ -148,30 +149,32 @@ OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr,
148OPTION(prefix_1, "machine:", machine, Joined, INVALID, INVALID, nullptr, 0, 0,149OPTION(prefix_1, "machine:", machine, Joined, INVALID, INVALID, nullptr, 0, 0,
149 "Specify target platform", nullptr, nullptr)150 "Specify target platform", nullptr, nullptr)
150OPTION(prefix_1, "manifest:", manifest_colon, Joined, INVALID, INVALID, nullptr, 0, 0,151OPTION(prefix_1, "manifest:", manifest_colon, Joined, INVALID, INVALID, nullptr, 0, 0,
151 "Create manifest file", nullptr, nullptr)152 "NO disables manifest output; EMBED[,ID=#] embeds manifest as resource in the image", nullptr, nullptr)
152OPTION(prefix_1, "manifestdependency:", manifestdependency, Joined, INVALID, INVALID, nullptr, 0, 0,153OPTION(prefix_1, "manifestdependency:", manifestdependency, Joined, INVALID, INVALID, nullptr, 0, 0,
153 "Attributes for <dependency> in manifest file", nullptr, nullptr)154 "Attributes for <dependency> element in manifest file; implies /manifest", nullptr, nullptr)
154OPTION(prefix_1, "manifestfile:", manifestfile, Joined, INVALID, INVALID, nullptr, 0, 0,155OPTION(prefix_1, "manifestfile:", manifestfile, Joined, INVALID, INVALID, nullptr, 0, 0,
155 "Manifest file path", nullptr, nullptr)156 "Manifest output path, with /manifest", nullptr, nullptr)
156OPTION(prefix_1, "manifestinput:", manifestinput, Joined, INVALID, INVALID, nullptr, 0, 0,157OPTION(prefix_1, "manifestinput:", manifestinput, Joined, INVALID, INVALID, nullptr, 0, 0,
157 "Specify manifest file", nullptr, nullptr)158 "Additional manifest inputs; only valid with /manifest:embed", nullptr, nullptr)
158OPTION(prefix_1, "manifestuac:", manifestuac, Joined, INVALID, INVALID, nullptr, 0, 0,159OPTION(prefix_1, "manifestuac:", manifestuac, Joined, INVALID, INVALID, nullptr, 0, 0,
159 "User access control", nullptr, nullptr)160 "User access control", nullptr, nullptr)
160OPTION(prefix_1, "manifest", manifest, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)161OPTION(prefix_1, "manifest", manifest, Flag, INVALID, INVALID, nullptr, 0, 0,
162 "Create .manifest file", nullptr, nullptr)
161OPTION(prefix_1, "maxilksize:", maxilksize, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)163OPTION(prefix_1, "maxilksize:", maxilksize, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
162OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0,164OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0,
163 "Combine sections", nullptr, nullptr)165 "Combine sections", nullptr, nullptr)
164OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0,166OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0,
165 "Options to pass to LLVM", nullptr, nullptr)167 "Options to pass to LLVM", nullptr, nullptr)
166OPTION(prefix_1, "msvclto", msvclto, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
167OPTION(prefix_1, "natvis:", natvis, Joined, INVALID, INVALID, nullptr, 0, 0,168OPTION(prefix_1, "natvis:", natvis, Joined, INVALID, INVALID, nullptr, 0, 0,
168 "Path to natvis file to embed in the PDB", nullptr, nullptr)169 "Path to natvis file to embed in the PDB", nullptr, nullptr)
169OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,170OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
170 "Do not use colors in diagnostics", nullptr, nullptr)171 "Do not use colors in diagnostics", nullptr, nullptr)
171OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,172OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,
172 "Remove a default library", nullptr, nullptr)173 "Remove a default library", nullptr, nullptr)
173OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)174OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0,
174OPTION(prefix_1, "noentry", noentry, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)175 "Remove all default libraries", nullptr, nullptr)
176OPTION(prefix_1, "noentry", noentry, Flag, INVALID, INVALID, nullptr, 0, 0,
177 "Don't add reference to DllMainCRTStartup; only valid with /dll", nullptr, nullptr)
175OPTION(prefix_1, "nologo", nologo, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)178OPTION(prefix_1, "nologo", nologo, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
176OPTION(prefix_1, "nxcompat:no", nxcompat_no, Flag, INVALID, INVALID, nullptr, 0, 0,179OPTION(prefix_1, "nxcompat:no", nxcompat_no, Flag, INVALID, INVALID, nullptr, 0, 0,
177 "Disable data execution provention", nullptr, nullptr)180 "Disable data execution provention", nullptr, nullptr)
deps/lld-prebuilt/ELF/Options.inc+19-1
...@@ -62,6 +62,8 @@ OPTION(prefix_1, "b", anonymous_16, Separate, INVALID, format, nullptr, 0, 0,...@@ -62,6 +62,8 @@ OPTION(prefix_1, "b", anonymous_16, Separate, INVALID, format, nullptr, 0, 0,
62OPTION(prefix_2, "call-graph-ordering-file=", call_graph_ordering_file_eq, Joined, INVALID, call_graph_ordering_file, nullptr, 0, 0,62OPTION(prefix_2, "call-graph-ordering-file=", call_graph_ordering_file_eq, Joined, INVALID, call_graph_ordering_file, nullptr, 0, 0,
63 "Layout sections to optimize the given callgraph", nullptr, nullptr)63 "Layout sections to optimize the given callgraph", nullptr, nullptr)
64OPTION(prefix_2, "call-graph-ordering-file", call_graph_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)64OPTION(prefix_2, "call-graph-ordering-file", call_graph_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
65OPTION(prefix_2, "call-graph-profile-sort", call_graph_profile_sort, Flag, INVALID, INVALID, nullptr, 0, 0,
66 "Reorder sections with call graph profile (default)", nullptr, nullptr)
65OPTION(prefix_2, "call_shared", anonymous_1, Flag, INVALID, Bdynamic, nullptr, 0, 0,67OPTION(prefix_2, "call_shared", anonymous_1, Flag, INVALID, Bdynamic, nullptr, 0, 0,
66 "Alias for --Bdynamic", nullptr, nullptr)68 "Alias for --Bdynamic", nullptr, nullptr)
67OPTION(prefix_2, "check-sections", check_sections, Flag, INVALID, INVALID, nullptr, 0, 0,69OPTION(prefix_2, "check-sections", check_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -133,7 +135,7 @@ OPTION(prefix_2, "exclude-libs=", exclude_libs_eq, Joined, INVALID, exclude_libs...@@ -133,7 +135,7 @@ OPTION(prefix_2, "exclude-libs=", exclude_libs_eq, Joined, INVALID, exclude_libs
133 "Exclude static libraries from automatic export", nullptr, nullptr)135 "Exclude static libraries from automatic export", nullptr, nullptr)
134OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)136OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
135OPTION(prefix_2, "execute-only", execute_only, Flag, INVALID, INVALID, nullptr, 0, 0,137OPTION(prefix_2, "execute-only", execute_only, Flag, INVALID, INVALID, nullptr, 0, 0,
136 "Do not mark executable sections readable", nullptr, nullptr)138 "Mark executable sections unreadable", nullptr, nullptr)
137OPTION(prefix_2, "export-dynamic-symbol=", export_dynamic_symbol_eq, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0,139OPTION(prefix_2, "export-dynamic-symbol=", export_dynamic_symbol_eq, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0,
138 "Put a symbol in the dynamic symbol table", nullptr, nullptr)140 "Put a symbol in the dynamic symbol table", nullptr, nullptr)
139OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)141OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
...@@ -245,6 +247,8 @@ OPTION(prefix_2, "no-apply-dynamic-relocs", no_apply_dynamic_relocs, Flag, INVAL...@@ -245,6 +247,8 @@ OPTION(prefix_2, "no-apply-dynamic-relocs", no_apply_dynamic_relocs, Flag, INVAL
245 "Do not apply link-time values for dynamic relocations (default)", nullptr, nullptr)247 "Do not apply link-time values for dynamic relocations (default)", nullptr, nullptr)
246OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,248OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
247 "Always set DT_NEEDED for shared libraries (default)", nullptr, nullptr)249 "Always set DT_NEEDED for shared libraries (default)", nullptr, nullptr)
250OPTION(prefix_2, "no-call-graph-profile-sort", no_call_graph_profile_sort, Flag, INVALID, INVALID, nullptr, 0, 0,
251 "Do not reorder sections with call graph profile", nullptr, nullptr)
248OPTION(prefix_2, "no-check-sections", no_check_sections, Flag, INVALID, INVALID, nullptr, 0, 0,252OPTION(prefix_2, "no-check-sections", no_check_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
249 "Do not check section addresses for overlaps", nullptr, nullptr)253 "Do not check section addresses for overlaps", nullptr, nullptr)
250OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,254OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -291,6 +295,8 @@ OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr,...@@ -291,6 +295,8 @@ OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr,
291 "Do not put read-only non-executable sections in their own segment", nullptr, nullptr)295 "Do not put read-only non-executable sections in their own segment", nullptr, nullptr)
292OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,296OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,
293 "Do not run the linker multi-threaded", nullptr, nullptr)297 "Do not run the linker multi-threaded", nullptr, nullptr)
298OPTION(prefix_2, "no-toc-optimize", no_toc_optimize, Flag, INVALID, INVALID, nullptr, 0, 0,
299 "(PowerPC64) Disable TOC related optimizations", nullptr, nullptr)
294OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0,300OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0,
295 "Report version scripts that refer undefined symbols", nullptr, nullptr)301 "Report version scripts that refer undefined symbols", nullptr, nullptr)
296OPTION(prefix_2, "no-undefined", no_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,302OPTION(prefix_2, "no-undefined", no_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -301,6 +307,8 @@ OPTION(prefix_2, "no-warn-backrefs", no_warn_backrefs, Flag, INVALID, INVALID, n...@@ -301,6 +307,8 @@ OPTION(prefix_2, "no-warn-backrefs", no_warn_backrefs, Flag, INVALID, INVALID, n
301 "Do not warn about backward symbol references to fetch archive members (default)", nullptr, nullptr)307 "Do not warn about backward symbol references to fetch archive members (default)", nullptr, nullptr)
302OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,308OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
303 "Do not warn about duplicate common symbols (default)", nullptr, nullptr)309 "Do not warn about duplicate common symbols (default)", nullptr, nullptr)
310OPTION(prefix_2, "no-warn-ifunc-textrel", no_warn_ifunc_textrel, Flag, INVALID, INVALID, nullptr, 0, 0,
311 "Do not warn about using ifunc symbols with text relocations (default)", nullptr, nullptr)
304OPTION(prefix_2, "no-warn-mismatch", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)312OPTION(prefix_2, "no-warn-mismatch", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
305OPTION(prefix_2, "no-warn-symbol-ordering", no_warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,313OPTION(prefix_2, "no-warn-symbol-ordering", no_warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,
306 "Do not warn about problems with the symbol ordering file", nullptr, nullptr)314 "Do not warn about problems with the symbol ordering file", nullptr, nullptr)
...@@ -338,6 +346,8 @@ OPTION(prefix_2, "pack-dyn-relocs=", pack_dyn_relocs_eq, Joined, INVALID, pack_d...@@ -338,6 +346,8 @@ OPTION(prefix_2, "pack-dyn-relocs=", pack_dyn_relocs_eq, Joined, INVALID, pack_d
338OPTION(prefix_2, "pack-dyn-relocs", pack_dyn_relocs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,android,relr,android+relr]", nullptr)346OPTION(prefix_2, "pack-dyn-relocs", pack_dyn_relocs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,android,relr,android+relr]", nullptr)
339OPTION(prefix_2, "pic-executable", anonymous_23, Flag, INVALID, pie, nullptr, 0, 0,347OPTION(prefix_2, "pic-executable", anonymous_23, Flag, INVALID, pie, nullptr, 0, 0,
340 "Alias for --pie", nullptr, nullptr)348 "Alias for --pie", nullptr, nullptr)
349OPTION(prefix_2, "pic-veneer", pic_veneer, Flag, INVALID, INVALID, nullptr, 0, 0,
350 "Always generate position independent thunks (veneers)", nullptr, nullptr)
341OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,351OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
342 "Create a position independent executable", nullptr, nullptr)352 "Create a position independent executable", nullptr, nullptr)
343OPTION(prefix_2, "plugin-opt=-fresolution=", plugin_opt_fresolution_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)353OPTION(prefix_2, "plugin-opt=-fresolution=", plugin_opt_fresolution_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
...@@ -349,6 +359,7 @@ OPTION(prefix_2, "plugin-opt=disable-verify", anonymous_41, Flag, INVALID, disab...@@ -349,6 +359,7 @@ OPTION(prefix_2, "plugin-opt=disable-verify", anonymous_41, Flag, INVALID, disab
349 "Alias for -disable-verify", nullptr, nullptr)359 "Alias for -disable-verify", nullptr, nullptr)
350OPTION(prefix_2, "plugin-opt=dwo_dir=", plugin_opt_dwo_dir_eq, Joined, INVALID, INVALID, nullptr, 0, 0,360OPTION(prefix_2, "plugin-opt=dwo_dir=", plugin_opt_dwo_dir_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
351 "Directory to store .dwo files when LTO and debug fission are used", nullptr, nullptr)361 "Directory to store .dwo files when LTO and debug fission are used", nullptr, nullptr)
362OPTION(prefix_2, "plugin-opt=emit-llvm", plugin_opt_emit_llvm, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
352OPTION(prefix_2, "plugin-opt=jobs=", anonymous_42, Joined, INVALID, thinlto_jobs, nullptr, 0, 0,363OPTION(prefix_2, "plugin-opt=jobs=", anonymous_42, Joined, INVALID, thinlto_jobs, nullptr, 0, 0,
353 "Alias for -thinlto-jobs", nullptr, nullptr)364 "Alias for -thinlto-jobs", nullptr, nullptr)
354OPTION(prefix_2, "plugin-opt=lto-partitions=", anonymous_43, Joined, INVALID, lto_partitions, nullptr, 0, 0,365OPTION(prefix_2, "plugin-opt=lto-partitions=", anonymous_43, Joined, INVALID, lto_partitions, nullptr, 0, 0,
...@@ -424,6 +435,9 @@ OPTION(prefix_2, "sort-common", anonymous_60, Flag, INVALID, INVALID, nullptr, 0...@@ -424,6 +435,9 @@ OPTION(prefix_2, "sort-common", anonymous_60, Flag, INVALID, INVALID, nullptr, 0
424OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0,435OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0,
425 "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr)436 "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr)
426OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)437OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
438OPTION(prefix_2, "split-stack-adjust-size=", split_stack_adjust_size_eq, Joined, INVALID, split_stack_adjust_size, nullptr, 0, 0,
439 "Specify adjustment to stack size when a split-stack function calls a non-split-stack function", "<value>", nullptr)
440OPTION(prefix_2, "split-stack-adjust-size", split_stack_adjust_size, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<value>", nullptr)
427OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0,441OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0,
428 "Ignored for compatibility with GNU unless you pass --warn-backrefs", nullptr, nullptr)442 "Ignored for compatibility with GNU unless you pass --warn-backrefs", nullptr, nullptr)
429OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0,443OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -467,6 +481,8 @@ OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullpt...@@ -467,6 +481,8 @@ OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullpt
467 "Number of ThinLTO jobs", nullptr, nullptr)481 "Number of ThinLTO jobs", nullptr, nullptr)
468OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,482OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
469 "Run the linker multi-threaded (default)", nullptr, nullptr)483 "Run the linker multi-threaded (default)", nullptr, nullptr)
484OPTION(prefix_2, "toc-optimize", toc_optimize, Flag, INVALID, INVALID, nullptr, 0, 0,
485 "(PowerPC64) Enable TOC related optimizations (default)", nullptr, nullptr)
470OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0,486OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0,
471 "Trace references to symbols", nullptr, nullptr)487 "Trace references to symbols", nullptr, nullptr)
472OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)488OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
...@@ -511,6 +527,8 @@ OPTION(prefix_2, "warn-backrefs", warn_backrefs, Flag, INVALID, INVALID, nullptr...@@ -511,6 +527,8 @@ OPTION(prefix_2, "warn-backrefs", warn_backrefs, Flag, INVALID, INVALID, nullptr
511OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,527OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
512 "Warn about duplicate common symbols", nullptr, nullptr)528 "Warn about duplicate common symbols", nullptr, nullptr)
513OPTION(prefix_2, "warn-execstack", anonymous_62, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)529OPTION(prefix_2, "warn-execstack", anonymous_62, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
530OPTION(prefix_2, "warn-ifunc-textrel", warn_ifunc_textrel, Flag, INVALID, INVALID, nullptr, 0, 0,
531 "Warn about using ifunc symbols with text relocations", nullptr, nullptr)
514OPTION(prefix_2, "warn-once", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)532OPTION(prefix_2, "warn-once", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
515OPTION(prefix_2, "warn-shared-textrel", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)533OPTION(prefix_2, "warn-shared-textrel", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
516OPTION(prefix_2, "warn-symbol-ordering", warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,534OPTION(prefix_2, "warn-symbol-ordering", warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,
deps/lld-prebuilt/MinGW/Options.inc+7
...@@ -90,6 +90,13 @@ OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,...@@ -90,6 +90,13 @@ OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
90OPTION(prefix_2, "pdb", pdb, Separate, INVALID, INVALID, nullptr, 0, 0,90OPTION(prefix_2, "pdb", pdb, Separate, INVALID, INVALID, nullptr, 0, 0,
91 "Specify output PDB debug information file", nullptr, nullptr)91 "Specify output PDB debug information file", nullptr, nullptr)
92OPTION(prefix_2, "pic-executable", pic_executable, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)92OPTION(prefix_2, "pic-executable", pic_executable, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93OPTION(prefix_2, "plugin-opt=", anonymous_3, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
94OPTION(prefix_2, "plugin-opt", anonymous_2, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
95OPTION(prefix_2, "plugin=", anonymous_1, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
96OPTION(prefix_2, "plugin", anonymous_0, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
97OPTION(prefix_2, "require-defined=", require_defined_eq, Joined, INVALID, require_defined, nullptr, 0, 0, nullptr, nullptr, nullptr)
98OPTION(prefix_2, "require-defined", require_defined, Separate, INVALID, INVALID, nullptr, 0, 0,
99 "Force symbol to be added to symbol table as an undefined one", nullptr, nullptr)
93OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,100OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
94 "Build a shared object", nullptr, nullptr)101 "Build a shared object", nullptr, nullptr)
95OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)102OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
deps/lld-prebuilt/lld/Common/Version.inc+3-3
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1#define LLD_VERSION 7.0.01#define LLD_VERSION 8.0.0
2#define LLD_VERSION_STRING "7.0.0"2#define LLD_VERSION_STRING "8.0.0"
3#define LLD_VERSION_MAJOR 73#define LLD_VERSION_MAJOR 8
4#define LLD_VERSION_MINOR 04#define LLD_VERSION_MINOR 0
5#define LLD_REVISION_STRING ""5#define LLD_REVISION_STRING ""
6#define LLD_REPOSITORY_STRING ""6#define LLD_REPOSITORY_STRING ""
deps/lld-prebuilt/wasm/Options.inc+29-12
...@@ -36,23 +36,28 @@ OPTION(prefix_1, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, IN...@@ -36,23 +36,28 @@ OPTION(prefix_1, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, IN
36 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)36 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)
37OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,37OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
38 "Use colors in diagnostics", nullptr, nullptr)38 "Use colors in diagnostics", nullptr, nullptr)
39OPTION(prefix_1, "compress-relocations", compress_relocations, Flag, INVALID, INVALID, nullptr, 0, 0,
40 "Compress the relocation targets in the code section.", nullptr, nullptr)
39OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,41OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
40 "Demangle symbol names", nullptr, nullptr)42 "Demangle symbol names", nullptr, nullptr)
41OPTION(prefix_1, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)43OPTION(prefix_1, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
42OPTION(prefix_1, "entry=", alias_entry_entry, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)44OPTION(prefix_1, "entry=", anonymous_1, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
43OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,45OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,
44 "Name of entry point symbol", "<entry>", nullptr)46 "Name of entry point symbol", "<entry>", nullptr)
45OPTION(prefix_1, "error-limit=", error_limit, Joined, INVALID, INVALID, nullptr, 0, 0,47OPTION(prefix_1, "error-limit=", error_limit, Joined, INVALID, INVALID, nullptr, 0, 0,
46 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)48 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)
47OPTION(prefix_1, "export-all", export_all, Flag, INVALID, INVALID, nullptr, 0, 0,49OPTION(prefix_1, "export-all", export_all, Flag, INVALID, INVALID, nullptr, 0, 0,
48 "Export all symbols (normally combined with --no-gc-sections)", nullptr, nullptr)50 "Export all symbols (normally combined with --no-gc-sections)", nullptr, nullptr)
51OPTION(prefix_1, "export-dynamic", export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
52 "Put symbols in the dynamic symbol table", nullptr, nullptr)
49OPTION(prefix_1, "export-table", export_table, Flag, INVALID, INVALID, nullptr, 0, 0,53OPTION(prefix_1, "export-table", export_table, Flag, INVALID, INVALID, nullptr, 0, 0,
50 "Export function table to the environment", nullptr, nullptr)54 "Export function table to the environment", nullptr, nullptr)
51OPTION(prefix_1, "export=", export_eq, Joined, INVALID, export, nullptr, 0, 0,55OPTION(prefix_1, "export=", export_eq, Joined, INVALID, export, nullptr, 0, 0,
52 "Force a symbol to be exported", nullptr, nullptr)56 "Force a symbol to be exported", nullptr, nullptr)
53OPTION(prefix_1, "export", export, Separate, INVALID, INVALID, nullptr, 0, 0,57OPTION(prefix_1, "export", export, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
54 "Force a symbol to be exported", nullptr, nullptr)58OPTION(prefix_2, "E", anonymous_2, Flag, INVALID, export_dynamic, nullptr, 0, 0,
55OPTION(prefix_2, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)59 "Alias for --export-dynamic", nullptr, nullptr)
60OPTION(prefix_2, "e", anonymous_0, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
56OPTION(prefix_1, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0,61OPTION(prefix_1, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0,
57 "Treat warnings as errors", nullptr, nullptr)62 "Treat warnings as errors", nullptr, nullptr)
58OPTION(prefix_1, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,63OPTION(prefix_1, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -67,7 +72,7 @@ OPTION(prefix_1, "import-table", import_table, Flag, INVALID, INVALID, nullptr,...@@ -67,7 +72,7 @@ OPTION(prefix_1, "import-table", import_table, Flag, INVALID, INVALID, nullptr,
67 "Import function table from the environment", nullptr, nullptr)72 "Import function table from the environment", nullptr, nullptr)
68OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0,73OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0,
69 "Initial size of the linear memory", nullptr, nullptr)74 "Initial size of the linear memory", nullptr, nullptr)
70OPTION(prefix_2, "i", alias_initial_memory_i, Flag, INVALID, initial_memory, nullptr, 0, 0, nullptr, nullptr, nullptr)75OPTION(prefix_2, "i", anonymous_3, Flag, INVALID, initial_memory, nullptr, 0, 0, nullptr, nullptr, nullptr)
71OPTION(prefix_1, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0,76OPTION(prefix_1, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0,
72 "Optimization level for LTO", "<opt-level>", nullptr)77 "Optimization level for LTO", "<opt-level>", nullptr)
73OPTION(prefix_1, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0,78OPTION(prefix_1, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0,
...@@ -82,18 +87,22 @@ OPTION(prefix_1, "merge-data-segments", merge_data_segments, Flag, INVALID, INVA...@@ -82,18 +87,22 @@ OPTION(prefix_1, "merge-data-segments", merge_data_segments, Flag, INVALID, INVA
82 "Enable merging data segments", nullptr, nullptr)87 "Enable merging data segments", nullptr, nullptr)
83OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0,88OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0,
84 "Options to pass to LLVM", nullptr, nullptr)89 "Options to pass to LLVM", nullptr, nullptr)
85OPTION(prefix_2, "m", alias_max_memory_m, Flag, INVALID, max_memory, nullptr, 0, 0, nullptr, nullptr, nullptr)90OPTION(prefix_2, "m", anonymous_4, Flag, INVALID, max_memory, nullptr, 0, 0, nullptr, nullptr, nullptr)
86OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,91OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
87 "Do not use colors in diagnostics", nullptr, nullptr)92 "Do not use colors in diagnostics", nullptr, nullptr)
88OPTION(prefix_1, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,93OPTION(prefix_1, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
89 "Do not demangle symbol names", nullptr, nullptr)94 "Do not demangle symbol names", nullptr, nullptr)
90OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0,95OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0,
91 "Do not output any entry point", nullptr, nullptr)96 "Do not output any entry point", nullptr, nullptr)
97OPTION(prefix_1, "no-export-dynamic", no_export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
98 "Do not put symbols in the dynamic symbol table (default)", nullptr, nullptr)
92OPTION(prefix_1, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)99OPTION(prefix_1, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93OPTION(prefix_1, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,100OPTION(prefix_1, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
94 "Disable garbage collection of unused sections", nullptr, nullptr)101 "Disable garbage collection of unused sections", nullptr, nullptr)
95OPTION(prefix_1, "no-merge-data-segments", no_merge_data_segments, Flag, INVALID, INVALID, nullptr, 0, 0,102OPTION(prefix_1, "no-merge-data-segments", no_merge_data_segments, Flag, INVALID, INVALID, nullptr, 0, 0,
96 "Disable merging data segments", nullptr, nullptr)103 "Disable merging data segments", nullptr, nullptr)
104OPTION(prefix_1, "no-pie", no_pie, Flag, INVALID, INVALID, nullptr, 0, 0,
105 "Do not create a position independent executable (default)", nullptr, nullptr)
97OPTION(prefix_1, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,106OPTION(prefix_1, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
98 "Do not list removed unused sections", nullptr, nullptr)107 "Do not list removed unused sections", nullptr, nullptr)
99OPTION(prefix_1, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,108OPTION(prefix_1, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,
...@@ -104,33 +113,41 @@ OPTION(prefix_2, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,...@@ -104,33 +113,41 @@ OPTION(prefix_2, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
104 "Optimize output file size", nullptr, nullptr)113 "Optimize output file size", nullptr, nullptr)
105OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,114OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
106 "Path to file to write output", "<path>", nullptr)115 "Path to file to write output", "<path>", nullptr)
116OPTION(prefix_1, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
117 "Create a position independent executable", nullptr, nullptr)
107OPTION(prefix_1, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,118OPTION(prefix_1, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
108 "List removed unused sections", nullptr, nullptr)119 "List removed unused sections", nullptr, nullptr)
109OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,120OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,
110 "Create relocatable object file", nullptr, nullptr)121 "Create relocatable object file", nullptr, nullptr)
111OPTION(prefix_2, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr)122OPTION(prefix_2, "r", anonymous_5, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr)
112OPTION(prefix_1, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)123OPTION(prefix_1, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
124OPTION(prefix_1, "shared-memory", shared_memory, Flag, INVALID, INVALID, nullptr, 0, 0,
125 "Use shared linear memory", nullptr, nullptr)
126OPTION(prefix_1, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
127 "Build a shared object", nullptr, nullptr)
113OPTION(prefix_1, "stack-first", stack_first, Flag, INVALID, INVALID, nullptr, 0, 0,128OPTION(prefix_1, "stack-first", stack_first, Flag, INVALID, INVALID, nullptr, 0, 0,
114 "Place stack at start of linear memory rather than after data", nullptr, nullptr)129 "Place stack at start of linear memory rather than after data", nullptr, nullptr)
115OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,130OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,
116 "Strip all symbols", nullptr, nullptr)131 "Strip all symbols", nullptr, nullptr)
117OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,132OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,
118 "Strip debugging information", nullptr, nullptr)133 "Strip debugging information", nullptr, nullptr)
134OPTION(prefix_2, "S", anonymous_7, Flag, INVALID, strip_debug, nullptr, 0, 0,
135 "Alias for --strip-debug", nullptr, nullptr)
136OPTION(prefix_2, "s", anonymous_6, Flag, INVALID, strip_all, nullptr, 0, 0,
137 "Alias for --strip-all", nullptr, nullptr)
119OPTION(prefix_1, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0,138OPTION(prefix_1, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0,
120 "Path to ThinLTO cached object file directory", nullptr, nullptr)139 "Path to ThinLTO cached object file directory", nullptr, nullptr)
121OPTION(prefix_1, "thinlto-cache-policy=", thinlto_cache_policy_eq, Joined, INVALID, thinlto_cache_policy, nullptr, 0, 0,140OPTION(prefix_1, "thinlto-cache-policy=", thinlto_cache_policy_eq, Joined, INVALID, thinlto_cache_policy, nullptr, 0, 0,
122 "Pruning policy for the ThinLTO cache", nullptr, nullptr)141 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
123OPTION(prefix_1, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0,142OPTION(prefix_1, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
124 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
125OPTION(prefix_1, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0,143OPTION(prefix_1, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0,
126 "Number of ThinLTO jobs", nullptr, nullptr)144 "Number of ThinLTO jobs", nullptr, nullptr)
127OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,145OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
128 "Run the linker multi-threaded", nullptr, nullptr)146 "Run the linker multi-threaded", nullptr, nullptr)
129OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0,147OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0,
130 "Force undefined symbol during linking", nullptr, nullptr)148 "Force undefined symbol during linking", nullptr, nullptr)
131OPTION(prefix_1, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0,149OPTION(prefix_1, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
132 "Force undefined symbol during linking", nullptr, nullptr)150OPTION(prefix_2, "u", anonymous_8, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
133OPTION(prefix_2, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
134OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,151OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
135 "Verbose mode", nullptr, nullptr)152 "Verbose mode", nullptr, nullptr)
136OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,153OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
deps/lld/COFF/Chunks.cpp+293-54
...@@ -11,6 +11,7 @@...@@ -11,6 +11,7 @@
11#include "InputFiles.h"11#include "InputFiles.h"
12#include "Symbols.h"12#include "Symbols.h"
13#include "Writer.h"13#include "Writer.h"
14#include "SymbolTable.h"
14#include "lld/Common/ErrorHandler.h"15#include "lld/Common/ErrorHandler.h"
15#include "llvm/ADT/Twine.h"16#include "llvm/ADT/Twine.h"
16#include "llvm/BinaryFormat/COFF.h"17#include "llvm/BinaryFormat/COFF.h"
...@@ -44,6 +45,22 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)...@@ -44,6 +45,22 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
44 Live = !Config->DoGC || !isCOMDAT();45 Live = !Config->DoGC || !isCOMDAT();
45}46}
4647
48// Initialize the RelocTargets vector, to allow redirecting certain relocations
49// to a thunk instead of the actual symbol the relocation's symbol table index
50// indicates.
51void SectionChunk::readRelocTargets() {
52 assert(RelocTargets.empty());
53 RelocTargets.reserve(Relocs.size());
54 for (const coff_relocation &Rel : Relocs)
55 RelocTargets.push_back(File->getSymbol(Rel.SymbolTableIndex));
56}
57
58// Reset RelocTargets to their original targets before thunks were added.
59void SectionChunk::resetRelocTargets() {
60 for (size_t I = 0, E = Relocs.size(); I < E; ++I)
61 RelocTargets[I] = File->getSymbol(Relocs[I].SymbolTableIndex);
62}
63
47static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }64static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
48static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }65static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
49static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }66static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
...@@ -58,7 +75,8 @@ static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) {...@@ -58,7 +75,8 @@ static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) {
58 return true;75 return true;
59 if (Sec->isCodeView())76 if (Sec->isCodeView())
60 return false;77 return false;
61 fatal("SECREL relocation cannot be applied to absolute symbols");78 error("SECREL relocation cannot be applied to absolute symbols");
79 return false;
62}80}
6381
64static void applySecRel(const SectionChunk *Sec, uint8_t *Off,82static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
...@@ -98,7 +116,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,...@@ -98,7 +116,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
98 case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;116 case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;
99 case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;117 case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;
100 default:118 default:
101 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +119 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
102 toString(File));120 toString(File));
103 }121 }
104}122}
...@@ -113,7 +131,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,...@@ -113,7 +131,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
113 case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;131 case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;
114 case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;132 case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;
115 default:133 default:
116 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +134 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
117 toString(File));135 toString(File));
118 }136 }
119}137}
...@@ -123,16 +141,22 @@ static void applyMOV(uint8_t *Off, uint16_t V) {...@@ -123,16 +141,22 @@ static void applyMOV(uint8_t *Off, uint16_t V) {
123 write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));141 write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
124}142}
125143
126static uint16_t readMOV(uint8_t *Off) {144static uint16_t readMOV(uint8_t *Off, bool MOVT) {
127 uint16_t Op1 = read16le(Off);145 uint16_t Op1 = read16le(Off);
146 if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
147 error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
148 " instruction in MOV32T relocation");
128 uint16_t Op2 = read16le(Off + 2);149 uint16_t Op2 = read16le(Off + 2);
150 if ((Op2 & 0x8000) != 0)
151 error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
152 " instruction in MOV32T relocation");
129 return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |153 return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
130 ((Op1 & 0x000f) << 12);154 ((Op1 & 0x000f) << 12);
131}155}
132156
133void applyMOV32T(uint8_t *Off, uint32_t V) {157void applyMOV32T(uint8_t *Off, uint32_t V) {
134 uint16_t ImmW = readMOV(Off); // read MOVW operand158 uint16_t ImmW = readMOV(Off, false); // read MOVW operand
135 uint16_t ImmT = readMOV(Off + 4); // read MOVT operand159 uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
136 uint32_t Imm = ImmW | (ImmT << 16);160 uint32_t Imm = ImmW | (ImmT << 16);
137 V += Imm; // add the immediate offset161 V += Imm; // add the immediate offset
138 applyMOV(Off, V); // set MOVW operand162 applyMOV(Off, V); // set MOVW operand
...@@ -141,7 +165,7 @@ void applyMOV32T(uint8_t *Off, uint32_t V) {...@@ -141,7 +165,7 @@ void applyMOV32T(uint8_t *Off, uint32_t V) {
141165
142static void applyBranch20T(uint8_t *Off, int32_t V) {166static void applyBranch20T(uint8_t *Off, int32_t V) {
143 if (!isInt<21>(V))167 if (!isInt<21>(V))
144 fatal("relocation out of range");168 error("relocation out of range");
145 uint32_t S = V < 0 ? 1 : 0;169 uint32_t S = V < 0 ? 1 : 0;
146 uint32_t J1 = (V >> 19) & 1;170 uint32_t J1 = (V >> 19) & 1;
147 uint32_t J2 = (V >> 18) & 1;171 uint32_t J2 = (V >> 18) & 1;
...@@ -151,7 +175,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) {...@@ -151,7 +175,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) {
151175
152void applyBranch24T(uint8_t *Off, int32_t V) {176void applyBranch24T(uint8_t *Off, int32_t V) {
153 if (!isInt<25>(V))177 if (!isInt<25>(V))
154 fatal("relocation out of range");178 error("relocation out of range");
155 uint32_t S = V < 0 ? 1 : 0;179 uint32_t S = V < 0 ? 1 : 0;
156 uint32_t J1 = ((~V >> 23) & 1) ^ S;180 uint32_t J1 = ((~V >> 23) & 1) ^ S;
157 uint32_t J2 = ((~V >> 22) & 1) ^ S;181 uint32_t J2 = ((~V >> 22) & 1) ^ S;
...@@ -176,7 +200,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,...@@ -176,7 +200,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
176 case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;200 case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
177 case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;201 case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
178 default:202 default:
179 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +203 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
180 toString(File));204 toString(File));
181 }205 }
182}206}
...@@ -184,7 +208,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,...@@ -184,7 +208,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
184// Interpret the existing immediate value as a byte offset to the208// Interpret the existing immediate value as a byte offset to the
185// target symbol, then update the instruction with the immediate as209// target symbol, then update the instruction with the immediate as
186// the page offset from the current instruction to the target.210// the page offset from the current instruction to the target.
187static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {211void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
188 uint32_t Orig = read32le(Off);212 uint32_t Orig = read32le(Off);
189 uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);213 uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
190 S += Imm;214 S += Imm;
...@@ -198,7 +222,7 @@ static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {...@@ -198,7 +222,7 @@ static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
198// Update the immediate field in a AARCH64 ldr, str, and add instruction.222// Update the immediate field in a AARCH64 ldr, str, and add instruction.
199// Optionally limit the range of the written immediate by one or more bits223// Optionally limit the range of the written immediate by one or more bits
200// (RangeLimit).224// (RangeLimit).
201static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {225void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
202 uint32_t Orig = read32le(Off);226 uint32_t Orig = read32le(Off);
203 Imm += (Orig >> 10) & 0xFFF;227 Imm += (Orig >> 10) & 0xFFF;
204 Orig &= ~(0xFFF << 10);228 Orig &= ~(0xFFF << 10);
...@@ -221,7 +245,7 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {...@@ -221,7 +245,7 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
221 if ((Orig & 0x4800000) == 0x4800000)245 if ((Orig & 0x4800000) == 0x4800000)
222 Size += 4;246 Size += 4;
223 if ((Imm & ((1 << Size) - 1)) != 0)247 if ((Imm & ((1 << Size) - 1)) != 0)
224 fatal("misaligned ldr/str offset");248 error("misaligned ldr/str offset");
225 applyArm64Imm(Off, Imm >> Size, Size);249 applyArm64Imm(Off, Imm >> Size, Size);
226}250}
227251
...@@ -250,21 +274,21 @@ static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off,...@@ -250,21 +274,21 @@ static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off,
250 applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);274 applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
251}275}
252276
253static void applyArm64Branch26(uint8_t *Off, int64_t V) {277void applyArm64Branch26(uint8_t *Off, int64_t V) {
254 if (!isInt<28>(V))278 if (!isInt<28>(V))
255 fatal("relocation out of range");279 error("relocation out of range");
256 or32(Off, (V & 0x0FFFFFFC) >> 2);280 or32(Off, (V & 0x0FFFFFFC) >> 2);
257}281}
258282
259static void applyArm64Branch19(uint8_t *Off, int64_t V) {283static void applyArm64Branch19(uint8_t *Off, int64_t V) {
260 if (!isInt<21>(V))284 if (!isInt<21>(V))
261 fatal("relocation out of range");285 error("relocation out of range");
262 or32(Off, (V & 0x001FFFFC) << 3);286 or32(Off, (V & 0x001FFFFC) << 3);
263}287}
264288
265static void applyArm64Branch14(uint8_t *Off, int64_t V) {289static void applyArm64Branch14(uint8_t *Off, int64_t V) {
266 if (!isInt<16>(V))290 if (!isInt<16>(V))
267 fatal("relocation out of range");291 error("relocation out of range");
268 or32(Off, (V & 0x0000FFFC) << 3);292 or32(Off, (V & 0x0000FFFC) << 3);
269}293}
270294
...@@ -287,11 +311,37 @@ void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,...@@ -287,11 +311,37 @@ void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
287 case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;311 case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;
288 case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;312 case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;
289 default:313 default:
290 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +314 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
291 toString(File));315 toString(File));
292 }316 }
293}317}
294318
319static void maybeReportRelocationToDiscarded(const SectionChunk *FromChunk,
320 Defined *Sym,
321 const coff_relocation &Rel) {
322 // Don't report these errors when the relocation comes from a debug info
323 // section or in mingw mode. MinGW mode object files (built by GCC) can
324 // have leftover sections with relocations against discarded comdat
325 // sections. Such sections are left as is, with relocations untouched.
326 if (FromChunk->isCodeView() || FromChunk->isDWARF() || Config->MinGW)
327 return;
328
329 // Get the name of the symbol. If it's null, it was discarded early, so we
330 // have to go back to the object file.
331 ObjFile *File = FromChunk->File;
332 StringRef Name;
333 if (Sym) {
334 Name = Sym->getName();
335 } else {
336 COFFSymbolRef COFFSym =
337 check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
338 File->getCOFFObj()->getSymbolName(COFFSym, Name);
339 }
340
341 error("relocation against symbol in discarded section: " + Name +
342 getSymbolLocations(File, Rel.SymbolTableIndex));
343}
344
295void SectionChunk::writeTo(uint8_t *Buf) const {345void SectionChunk::writeTo(uint8_t *Buf) const {
296 if (!hasData())346 if (!hasData())
297 return;347 return;
...@@ -302,46 +352,40 @@ void SectionChunk::writeTo(uint8_t *Buf) const {...@@ -302,46 +352,40 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
302352
303 // Apply relocations.353 // Apply relocations.
304 size_t InputSize = getSize();354 size_t InputSize = getSize();
305 for (const coff_relocation &Rel : Relocs) {355 for (size_t I = 0, E = Relocs.size(); I < E; I++) {
356 const coff_relocation &Rel = Relocs[I];
357
306 // Check for an invalid relocation offset. This check isn't perfect, because358 // Check for an invalid relocation offset. This check isn't perfect, because
307 // we don't have the relocation size, which is only known after checking the359 // we don't have the relocation size, which is only known after checking the
308 // machine and relocation type. As a result, a relocation may overwrite the360 // machine and relocation type. As a result, a relocation may overwrite the
309 // beginning of the following input section.361 // beginning of the following input section.
310 if (Rel.VirtualAddress >= InputSize)362 if (Rel.VirtualAddress >= InputSize) {
311 fatal("relocation points beyond the end of its parent section");363 error("relocation points beyond the end of its parent section");
364 continue;
365 }
312366
313 uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;367 uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
314368
369 // Use the potentially remapped Symbol instead of the one that the
370 // relocation points to.
371 auto *Sym = dyn_cast_or_null<Defined>(RelocTargets[I]);
372
315 // Get the output section of the symbol for this relocation. The output373 // Get the output section of the symbol for this relocation. The output
316 // section is needed to compute SECREL and SECTION relocations used in debug374 // section is needed to compute SECREL and SECTION relocations used in debug
317 // info.375 // info.
318 auto *Sym =376 Chunk *C = Sym ? Sym->getChunk() : nullptr;
319 dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
320 if (!Sym) {
321 if (isCodeView() || isDWARF())
322 continue;
323 // Symbols in early discarded sections are represented using null pointers,
324 // so we need to retrieve the name from the object file.
325 COFFSymbolRef Sym =
326 check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
327 StringRef Name;
328 File->getCOFFObj()->getSymbolName(Sym, Name);
329 fatal("relocation against symbol in discarded section: " + Name);
330 }
331 Chunk *C = Sym->getChunk();
332 OutputSection *OS = C ? C->getOutputSection() : nullptr;377 OutputSection *OS = C ? C->getOutputSection() : nullptr;
333378
334 // Only absolute and __ImageBase symbols lack an output section. For any379 // Skip the relocation if it refers to a discarded section, and diagnose it
335 // other symbol, this indicates that the chunk was discarded. Normally380 // as an error if appropriate. If a symbol was discarded early, it may be
336 // relocations against discarded sections are an error. However, debug info381 // null. If it was discarded late, the output section will be null, unless
337 // sections are not GC roots and can end up with these kinds of relocations.382 // it was an absolute or synthetic symbol.
338 // Skip these relocations.383 if (!Sym ||
339 if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {384 (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym))) {
340 if (isCodeView() || isDWARF())385 maybeReportRelocationToDiscarded(this, Sym, Rel);
341 continue;386 continue;
342 fatal("relocation against symbol in discarded section: " +
343 Sym->getName());
344 }387 }
388
345 uint64_t S = Sym->getRVA();389 uint64_t S = Sym->getRVA();
346390
347 // Compute the RVA of the relocation for relative relocations.391 // Compute the RVA of the relocation for relative relocations.
...@@ -399,17 +443,125 @@ static uint8_t getBaserelType(const coff_relocation &Rel) {...@@ -399,17 +443,125 @@ static uint8_t getBaserelType(const coff_relocation &Rel) {
399// fixed by the loader if load-time relocation is needed.443// fixed by the loader if load-time relocation is needed.
400// Only called when base relocation is enabled.444// Only called when base relocation is enabled.
401void SectionChunk::getBaserels(std::vector<Baserel> *Res) {445void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
402 for (const coff_relocation &Rel : Relocs) {446 for (size_t I = 0, E = Relocs.size(); I < E; I++) {
447 const coff_relocation &Rel = Relocs[I];
403 uint8_t Ty = getBaserelType(Rel);448 uint8_t Ty = getBaserelType(Rel);
404 if (Ty == IMAGE_REL_BASED_ABSOLUTE)449 if (Ty == IMAGE_REL_BASED_ABSOLUTE)
405 continue;450 continue;
406 Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);451 // Use the potentially remapped Symbol instead of the one that the
452 // relocation points to.
453 Symbol *Target = RelocTargets[I];
407 if (!Target || isa<DefinedAbsolute>(Target))454 if (!Target || isa<DefinedAbsolute>(Target))
408 continue;455 continue;
409 Res->emplace_back(RVA + Rel.VirtualAddress, Ty);456 Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
410 }457 }
411}458}
412459
460// MinGW specific.
461// Check whether a static relocation of type Type can be deferred and
462// handled at runtime as a pseudo relocation (for references to a module
463// local variable, which turned out to actually need to be imported from
464// another DLL) This returns the size the relocation is supposed to update,
465// in bits, or 0 if the relocation cannot be handled as a runtime pseudo
466// relocation.
467static int getRuntimePseudoRelocSize(uint16_t Type) {
468 // Relocations that either contain an absolute address, or a plain
469 // relative offset, since the runtime pseudo reloc implementation
470 // adds 8/16/32/64 bit values to a memory address.
471 //
472 // Given a pseudo relocation entry,
473 //
474 // typedef struct {
475 // DWORD sym;
476 // DWORD target;
477 // DWORD flags;
478 // } runtime_pseudo_reloc_item_v2;
479 //
480 // the runtime relocation performs this adjustment:
481 // *(base + .target) += *(base + .sym) - (base + .sym)
482 //
483 // This works for both absolute addresses (IMAGE_REL_*_ADDR32/64,
484 // IMAGE_REL_I386_DIR32, where the memory location initially contains
485 // the address of the IAT slot, and for relative addresses (IMAGE_REL*_REL32),
486 // where the memory location originally contains the relative offset to the
487 // IAT slot.
488 //
489 // This requires the target address to be writable, either directly out of
490 // the image, or temporarily changed at runtime with VirtualProtect.
491 // Since this only operates on direct address values, it doesn't work for
492 // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations.
493 switch (Config->Machine) {
494 case AMD64:
495 switch (Type) {
496 case IMAGE_REL_AMD64_ADDR64:
497 return 64;
498 case IMAGE_REL_AMD64_ADDR32:
499 case IMAGE_REL_AMD64_REL32:
500 case IMAGE_REL_AMD64_REL32_1:
501 case IMAGE_REL_AMD64_REL32_2:
502 case IMAGE_REL_AMD64_REL32_3:
503 case IMAGE_REL_AMD64_REL32_4:
504 case IMAGE_REL_AMD64_REL32_5:
505 return 32;
506 default:
507 return 0;
508 }
509 case I386:
510 switch (Type) {
511 case IMAGE_REL_I386_DIR32:
512 case IMAGE_REL_I386_REL32:
513 return 32;
514 default:
515 return 0;
516 }
517 case ARMNT:
518 switch (Type) {
519 case IMAGE_REL_ARM_ADDR32:
520 return 32;
521 default:
522 return 0;
523 }
524 case ARM64:
525 switch (Type) {
526 case IMAGE_REL_ARM64_ADDR64:
527 return 64;
528 case IMAGE_REL_ARM64_ADDR32:
529 return 32;
530 default:
531 return 0;
532 }
533 default:
534 llvm_unreachable("unknown machine type");
535 }
536}
537
538// MinGW specific.
539// Append information to the provided vector about all relocations that
540// need to be handled at runtime as runtime pseudo relocations (references
541// to a module local variable, which turned out to actually need to be
542// imported from another DLL).
543void SectionChunk::getRuntimePseudoRelocs(
544 std::vector<RuntimePseudoReloc> &Res) {
545 for (const coff_relocation &Rel : Relocs) {
546 auto *Target =
547 dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
548 if (!Target || !Target->IsRuntimePseudoReloc)
549 continue;
550 int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);
551 if (SizeInBits == 0) {
552 error("unable to automatically import from " + Target->getName() +
553 " with relocation type " +
554 File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " +
555 toString(File));
556 continue;
557 }
558 // SizeInBits is used to initialize the Flags field; currently no
559 // other flags are defined.
560 Res.emplace_back(
561 RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits));
562 }
563}
564
413bool SectionChunk::hasData() const {565bool SectionChunk::hasData() const {
414 return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);566 return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
415}567}
...@@ -447,6 +599,13 @@ void SectionChunk::replace(SectionChunk *Other) {...@@ -447,6 +599,13 @@ void SectionChunk::replace(SectionChunk *Other) {
447 Other->Live = false;599 Other->Live = false;
448}600}
449601
602uint32_t SectionChunk::getSectionNumber() const {
603 DataRefImpl R;
604 R.p = reinterpret_cast<uintptr_t>(Header);
605 SectionRef S(R, File->getCOFFObj());
606 return S.getIndex() + 1;
607}
608
450CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {609CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
451 // Common symbols are aligned on natural boundaries up to 32 bytes.610 // Common symbols are aligned on natural boundaries up to 32 bytes.
452 // This is what MSVC link.exe does.611 // This is what MSVC link.exe does.
...@@ -460,6 +619,7 @@ uint32_t CommonChunk::getOutputCharacteristics() const {...@@ -460,6 +619,7 @@ uint32_t CommonChunk::getOutputCharacteristics() const {
460619
461void StringChunk::writeTo(uint8_t *Buf) const {620void StringChunk::writeTo(uint8_t *Buf) const {
462 memcpy(Buf + OutputSectionOff, Str.data(), Str.size());621 memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
622 Buf[OutputSectionOff + Str.size()] = '\0';
463}623}
464624
465ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {625ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
...@@ -502,13 +662,50 @@ void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {...@@ -502,13 +662,50 @@ void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
502 applyArm64Ldr(Buf + OutputSectionOff + 4, Off);662 applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
503}663}
504664
665// A Thumb2, PIC, non-interworking range extension thunk.
666const uint8_t ArmThunk[] = {
667 0x40, 0xf2, 0x00, 0x0c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
668 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
669 0xe7, 0x44, // L1: add pc, ip
670};
671
672size_t RangeExtensionThunkARM::getSize() const {
673 assert(Config->Machine == ARMNT);
674 return sizeof(ArmThunk);
675}
676
677void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
678 assert(Config->Machine == ARMNT);
679 uint64_t Offset = Target->getRVA() - RVA - 12;
680 memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
681 applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
682}
683
684// A position independent ARM64 adrp+add thunk, with a maximum range of
685// +/- 4 GB, which is enough for any PE-COFF.
686const uint8_t Arm64Thunk[] = {
687 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
688 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest
689 0x00, 0x02, 0x1f, 0xd6, // br x16
690};
691
692size_t RangeExtensionThunkARM64::getSize() const {
693 assert(Config->Machine == ARM64);
694 return sizeof(Arm64Thunk);
695}
696
697void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
698 assert(Config->Machine == ARM64);
699 memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
700 applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
701 applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
702}
703
505void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {704void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
506 Res->emplace_back(getRVA());705 Res->emplace_back(getRVA());
507}706}
508707
509size_t LocalImportChunk::getSize() const {708size_t LocalImportChunk::getSize() const { return Config->Wordsize; }
510 return Config->is64() ? 8 : 4;
511}
512709
513void LocalImportChunk::writeTo(uint8_t *Buf) const {710void LocalImportChunk::writeTo(uint8_t *Buf) const {
514 if (Config->is64()) {711 if (Config->is64()) {
...@@ -528,6 +725,34 @@ void RVATableChunk::writeTo(uint8_t *Buf) const {...@@ -528,6 +725,34 @@ void RVATableChunk::writeTo(uint8_t *Buf) const {
528 "RVA tables should be de-duplicated");725 "RVA tables should be de-duplicated");
529}726}
530727
728// MinGW specific, for the "automatic import of variables from DLLs" feature.
729size_t PseudoRelocTableChunk::getSize() const {
730 if (Relocs.empty())
731 return 0;
732 return 12 + 12 * Relocs.size();
733}
734
735// MinGW specific.
736void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
737 if (Relocs.empty())
738 return;
739
740 ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
741 // This is the list header, to signal the runtime pseudo relocation v2
742 // format.
743 Table[0] = 0;
744 Table[1] = 0;
745 Table[2] = 1;
746
747 size_t Idx = 3;
748 for (const RuntimePseudoReloc &RPR : Relocs) {
749 Table[Idx + 0] = RPR.Sym->getRVA();
750 Table[Idx + 1] = RPR.Target->getRVA() + RPR.TargetOffset;
751 Table[Idx + 2] = RPR.Flags;
752 Idx += 3;
753 }
754}
755
531// Windows-specific. This class represents a block in .reloc section.756// Windows-specific. This class represents a block in .reloc section.
532// The format is described here.757// The format is described here.
533//758//
...@@ -613,13 +838,16 @@ void MergeChunk::addSection(SectionChunk *C) {...@@ -613,13 +838,16 @@ void MergeChunk::addSection(SectionChunk *C) {
613}838}
614839
615void MergeChunk::finalizeContents() {840void MergeChunk::finalizeContents() {
616 for (SectionChunk *C : Sections)841 if (!Finalized) {
617 if (C->isLive())842 for (SectionChunk *C : Sections)
618 Builder.add(toStringRef(C->getContents()));843 if (C->Live)
619 Builder.finalize();844 Builder.add(toStringRef(C->getContents()));
845 Builder.finalize();
846 Finalized = true;
847 }
620848
621 for (SectionChunk *C : Sections) {849 for (SectionChunk *C : Sections) {
622 if (!C->isLive())850 if (!C->Live)
623 continue;851 continue;
624 size_t Off = Builder.getOffset(toStringRef(C->getContents()));852 size_t Off = Builder.getOffset(toStringRef(C->getContents()));
625 C->setOutputSection(Out);853 C->setOutputSection(Out);
...@@ -640,5 +868,16 @@ void MergeChunk::writeTo(uint8_t *Buf) const {...@@ -640,5 +868,16 @@ void MergeChunk::writeTo(uint8_t *Buf) const {
640 Builder.write(Buf + OutputSectionOff);868 Builder.write(Buf + OutputSectionOff);
641}869}
642870
871// MinGW specific.
872size_t AbsolutePointerChunk::getSize() const { return Config->Wordsize; }
873
874void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
875 if (Config->is64()) {
876 write64le(Buf + OutputSectionOff, Value);
877 } else {
878 write32le(Buf + OutputSectionOff, Value);
879 }
880}
881
643} // namespace coff882} // namespace coff
644} // namespace lld883} // namespace lld
deps/lld/COFF/Chunks.h+114-16
...@@ -36,6 +36,7 @@ class DefinedImportData;...@@ -36,6 +36,7 @@ class DefinedImportData;
36class DefinedRegular;36class DefinedRegular;
37class ObjFile;37class ObjFile;
38class OutputSection;38class OutputSection;
39class RuntimePseudoReloc;
39class Symbol;40class Symbol;
4041
41// Mask for permissions (discardable, writable, readable, executable, etc).42// Mask for permissions (discardable, writable, readable, executable, etc).
...@@ -63,6 +64,13 @@ public:...@@ -63,6 +64,13 @@ public:
63 // before calling this function.64 // before calling this function.
64 virtual void writeTo(uint8_t *Buf) const {}65 virtual void writeTo(uint8_t *Buf) const {}
6566
67 // Called by the writer once before assigning addresses and writing
68 // the output.
69 virtual void readRelocTargets() {}
70
71 // Called if restarting thunk addition.
72 virtual void resetRelocTargets() {}
73
66 // Called by the writer after an RVA is assigned, but before calling74 // Called by the writer after an RVA is assigned, but before calling
67 // getSize().75 // getSize().
68 virtual void finalizeContents() {}76 virtual void finalizeContents() {}
...@@ -114,6 +122,10 @@ protected:...@@ -114,6 +122,10 @@ protected:
114public:122public:
115 // The offset from beginning of the output section. The writer sets a value.123 // The offset from beginning of the output section. The writer sets a value.
116 uint64_t OutputSectionOff = 0;124 uint64_t OutputSectionOff = 0;
125
126 // Whether this section needs to be kept distinct from other sections during
127 // ICF. This is set by the driver using address-significance tables.
128 bool KeepUnique = false;
117};129};
118130
119// A chunk corresponding a section of an input file.131// A chunk corresponding a section of an input file.
...@@ -140,6 +152,8 @@ public:...@@ -140,6 +152,8 @@ public:
140152
141 SectionChunk(ObjFile *File, const coff_section *Header);153 SectionChunk(ObjFile *File, const coff_section *Header);
142 static bool classof(const Chunk *C) { return C->kind() == SectionKind; }154 static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
155 void readRelocTargets() override;
156 void resetRelocTargets() override;
143 size_t getSize() const override { return Header->SizeOfRawData; }157 size_t getSize() const override { return Header->SizeOfRawData; }
144 ArrayRef<uint8_t> getContents() const;158 ArrayRef<uint8_t> getContents() const;
145 void writeTo(uint8_t *Buf) const override;159 void writeTo(uint8_t *Buf) const override;
...@@ -157,6 +171,8 @@ public:...@@ -157,6 +171,8 @@ public:
157 void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,171 void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
158 uint64_t P) const;172 uint64_t P) const;
159173
174 void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &Res);
175
160 // Called if the garbage collector decides to not include this chunk176 // Called if the garbage collector decides to not include this chunk
161 // in a final output. It's supposed to print out a log message to stdout.177 // in a final output. It's supposed to print out a log message to stdout.
162 void printDiscardedMessage() const;178 void printDiscardedMessage() const;
...@@ -167,16 +183,6 @@ public:...@@ -167,16 +183,6 @@ public:
167183
168 StringRef getDebugName() override;184 StringRef getDebugName() override;
169185
170 // Returns true if the chunk was not dropped by GC.
171 bool isLive() { return Live; }
172
173 // Used by the garbage collector.
174 void markLive() {
175 assert(Config->DoGC && "should only mark things live from GC");
176 assert(!isLive() && "Cannot mark an already live section!");
177 Live = true;
178 }
179
180 // True if this is a codeview debug info chunk. These will not be laid out in186 // True if this is a codeview debug info chunk. These will not be laid out in
181 // the image. Instead they will end up in the PDB, if one is requested.187 // the image. Instead they will end up in the PDB, if one is requested.
182 bool isCodeView() const {188 bool isCodeView() const {
...@@ -197,10 +203,13 @@ public:...@@ -197,10 +203,13 @@ public:
197 // Allow iteration over the associated child chunks for this section.203 // Allow iteration over the associated child chunks for this section.
198 ArrayRef<SectionChunk *> children() const { return AssocChildren; }204 ArrayRef<SectionChunk *> children() const { return AssocChildren; }
199205
206 // The section ID this chunk belongs to in its Obj.
207 uint32_t getSectionNumber() const;
208
200 // A pointer pointing to a replacement for this chunk.209 // A pointer pointing to a replacement for this chunk.
201 // Initially it points to "this" object. If this chunk is merged210 // Initially it points to "this" object. If this chunk is merged
202 // with other chunk by ICF, it points to another chunk,211 // with other chunk by ICF, it points to another chunk,
203 // and this chunk is considrered as dead.212 // and this chunk is considered as dead.
204 SectionChunk *Repl;213 SectionChunk *Repl;
205214
206 // The CRC of the contents as described in the COFF spec 4.5.5.215 // The CRC of the contents as described in the COFF spec 4.5.5.
...@@ -217,13 +226,17 @@ public:...@@ -217,13 +226,17 @@ public:
217226
218 ArrayRef<coff_relocation> Relocs;227 ArrayRef<coff_relocation> Relocs;
219228
229 // Used by the garbage collector.
230 bool Live;
231
232 // When inserting a thunk, we need to adjust a relocation to point to
233 // the thunk instead of the actual original target Symbol.
234 std::vector<Symbol *> RelocTargets;
235
220private:236private:
221 StringRef SectionName;237 StringRef SectionName;
222 std::vector<SectionChunk *> AssocChildren;238 std::vector<SectionChunk *> AssocChildren;
223239
224 // Used by the garbage collector.
225 bool Live;
226
227 // Used for ICF (Identical COMDAT Folding)240 // Used for ICF (Identical COMDAT Folding)
228 void replace(SectionChunk *Other);241 void replace(SectionChunk *Other);
229 uint32_t Class[2] = {0, 0};242 uint32_t Class[2] = {0, 0};
...@@ -254,6 +267,7 @@ public:...@@ -254,6 +267,7 @@ public:
254267
255private:268private:
256 llvm::StringTableBuilder Builder;269 llvm::StringTableBuilder Builder;
270 bool Finalized = false;
257};271};
258272
259// A chunk for common symbols. Common chunks don't have actual data.273// A chunk for common symbols. Common chunks don't have actual data.
...@@ -297,7 +311,7 @@ static const uint8_t ImportThunkARM64[] = {...@@ -297,7 +311,7 @@ static const uint8_t ImportThunkARM64[] = {
297};311};
298312
299// Windows-specific.313// Windows-specific.
300// A chunk for DLL import jump table entry. In a final output, it's314// A chunk for DLL import jump table entry. In a final output, its
301// contents will be a JMP instruction to some __imp_ symbol.315// contents will be a JMP instruction to some __imp_ symbol.
302class ImportThunkChunkX64 : public Chunk {316class ImportThunkChunkX64 : public Chunk {
303public:317public:
...@@ -341,11 +355,31 @@ private:...@@ -341,11 +355,31 @@ private:
341 Defined *ImpSymbol;355 Defined *ImpSymbol;
342};356};
343357
358class RangeExtensionThunkARM : public Chunk {
359public:
360 explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
361 size_t getSize() const override;
362 void writeTo(uint8_t *Buf) const override;
363
364 Defined *Target;
365};
366
367class RangeExtensionThunkARM64 : public Chunk {
368public:
369 explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
370 size_t getSize() const override;
371 void writeTo(uint8_t *Buf) const override;
372
373 Defined *Target;
374};
375
344// Windows-specific.376// Windows-specific.
345// See comments for DefinedLocalImport class.377// See comments for DefinedLocalImport class.
346class LocalImportChunk : public Chunk {378class LocalImportChunk : public Chunk {
347public:379public:
348 explicit LocalImportChunk(Defined *S) : Sym(S) {}380 explicit LocalImportChunk(Defined *S) : Sym(S) {
381 Alignment = Config->Wordsize;
382 }
349 size_t getSize() const override;383 size_t getSize() const override;
350 void getBaserels(std::vector<Baserel> *Res) override;384 void getBaserels(std::vector<Baserel> *Res) override;
351 void writeTo(uint8_t *Buf) const override;385 void writeTo(uint8_t *Buf) const override;
...@@ -414,9 +448,73 @@ public:...@@ -414,9 +448,73 @@ public:
414 uint8_t Type;448 uint8_t Type;
415};449};
416450
451// This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a
452// specific place in a section, without any data. This is used for the MinGW
453// specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept
454// of an empty chunk isn't MinGW specific.
455class EmptyChunk : public Chunk {
456public:
457 EmptyChunk() {}
458 size_t getSize() const override { return 0; }
459 void writeTo(uint8_t *Buf) const override {}
460};
461
462// MinGW specific, for the "automatic import of variables from DLLs" feature.
463// This provides the table of runtime pseudo relocations, for variable
464// references that turned out to need to be imported from a DLL even though
465// the reference didn't use the dllimport attribute. The MinGW runtime will
466// process this table after loading, before handling control over to user
467// code.
468class PseudoRelocTableChunk : public Chunk {
469public:
470 PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
471 : Relocs(std::move(Relocs)) {
472 Alignment = 4;
473 }
474 size_t getSize() const override;
475 void writeTo(uint8_t *Buf) const override;
476
477private:
478 std::vector<RuntimePseudoReloc> Relocs;
479};
480
481// MinGW specific; information about one individual location in the image
482// that needs to be fixed up at runtime after loading. This represents
483// one individual element in the PseudoRelocTableChunk table.
484class RuntimePseudoReloc {
485public:
486 RuntimePseudoReloc(Defined *Sym, SectionChunk *Target, uint32_t TargetOffset,
487 int Flags)
488 : Sym(Sym), Target(Target), TargetOffset(TargetOffset), Flags(Flags) {}
489
490 Defined *Sym;
491 SectionChunk *Target;
492 uint32_t TargetOffset;
493 // The Flags field contains the size of the relocation, in bits. No other
494 // flags are currently defined.
495 int Flags;
496};
497
498// MinGW specific. A Chunk that contains one pointer-sized absolute value.
499class AbsolutePointerChunk : public Chunk {
500public:
501 AbsolutePointerChunk(uint64_t Value) : Value(Value) {
502 Alignment = getSize();
503 }
504 size_t getSize() const override;
505 void writeTo(uint8_t *Buf) const override;
506
507private:
508 uint64_t Value;
509};
510
417void applyMOV32T(uint8_t *Off, uint32_t V);511void applyMOV32T(uint8_t *Off, uint32_t V);
418void applyBranch24T(uint8_t *Off, int32_t V);512void applyBranch24T(uint8_t *Off, int32_t V);
419513
514void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift);
515void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit);
516void applyArm64Branch26(uint8_t *Off, int64_t V);
517
420} // namespace coff518} // namespace coff
421} // namespace lld519} // namespace lld
422520
deps/lld/COFF/Config.h+4-1
...@@ -84,6 +84,7 @@ struct Configuration {...@@ -84,6 +84,7 @@ struct Configuration {
84 bool is64() { return Machine == AMD64 || Machine == ARM64; }84 bool is64() { return Machine == AMD64 || Machine == ARM64; }
8585
86 llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;86 llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
87 size_t Wordsize;
87 bool Verbose = false;88 bool Verbose = false;
88 WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;89 WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
89 Symbol *Entry = nullptr;90 Symbol *Entry = nullptr;
...@@ -94,7 +95,8 @@ struct Configuration {...@@ -94,7 +95,8 @@ struct Configuration {
94 bool DoICF = true;95 bool DoICF = true;
95 bool TailMerge;96 bool TailMerge;
96 bool Relocatable = true;97 bool Relocatable = true;
97 bool Force = false;98 bool ForceMultiple = false;
99 bool ForceUnresolved = false;
98 bool Debug = false;100 bool Debug = false;
99 bool DebugDwarf = false;101 bool DebugDwarf = false;
100 bool DebugGHashes = false;102 bool DebugGHashes = false;
...@@ -195,6 +197,7 @@ struct Configuration {...@@ -195,6 +197,7 @@ struct Configuration {
195 bool MinGW = false;197 bool MinGW = false;
196 bool WarnMissingOrderSymbol = true;198 bool WarnMissingOrderSymbol = true;
197 bool WarnLocallyDefinedImported = true;199 bool WarnLocallyDefinedImported = true;
200 bool WarnDebugInfoUnusable = true;
198 bool Incremental = true;201 bool Incremental = true;
199 bool IntegrityCheck = false;202 bool IntegrityCheck = false;
200 bool KillAt = false;203 bool KillAt = false;
deps/lld/COFF/DLL.cpp+83-35
...@@ -35,8 +35,6 @@ namespace {...@@ -35,8 +35,6 @@ namespace {
3535
36// Import table36// Import table
3737
38static int ptrSize() { return Config->is64() ? 8 : 4; }
39
40// A chunk for the import descriptor table.38// A chunk for the import descriptor table.
41class HintNameChunk : public Chunk {39class HintNameChunk : public Chunk {
42public:40public:
...@@ -49,6 +47,7 @@ public:...@@ -49,6 +47,7 @@ public:
49 }47 }
5048
51 void writeTo(uint8_t *Buf) const override {49 void writeTo(uint8_t *Buf) const override {
50 memset(Buf + OutputSectionOff, 0, getSize());
52 write16le(Buf + OutputSectionOff, Hint);51 write16le(Buf + OutputSectionOff, Hint);
53 memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());52 memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
54 }53 }
...@@ -61,11 +60,14 @@ private:...@@ -61,11 +60,14 @@ private:
61// A chunk for the import descriptor table.60// A chunk for the import descriptor table.
62class LookupChunk : public Chunk {61class LookupChunk : public Chunk {
63public:62public:
64 explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = ptrSize(); }63 explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = Config->Wordsize; }
65 size_t getSize() const override { return ptrSize(); }64 size_t getSize() const override { return Config->Wordsize; }
6665
67 void writeTo(uint8_t *Buf) const override {66 void writeTo(uint8_t *Buf) const override {
68 write32le(Buf + OutputSectionOff, HintName->getRVA());67 if (Config->is64())
68 write64le(Buf + OutputSectionOff, HintName->getRVA());
69 else
70 write32le(Buf + OutputSectionOff, HintName->getRVA());
69 }71 }
7072
71 Chunk *HintName;73 Chunk *HintName;
...@@ -76,8 +78,10 @@ public:...@@ -76,8 +78,10 @@ public:
76// See Microsoft PE/COFF spec 7.1. Import Header for details.78// See Microsoft PE/COFF spec 7.1. Import Header for details.
77class OrdinalOnlyChunk : public Chunk {79class OrdinalOnlyChunk : public Chunk {
78public:80public:
79 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { Alignment = ptrSize(); }81 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
80 size_t getSize() const override { return ptrSize(); }82 Alignment = Config->Wordsize;
83 }
84 size_t getSize() const override { return Config->Wordsize; }
8185
82 void writeTo(uint8_t *Buf) const override {86 void writeTo(uint8_t *Buf) const override {
83 // An import-by-ordinal slot has MSB 1 to indicate that87 // An import-by-ordinal slot has MSB 1 to indicate that
...@@ -99,6 +103,8 @@ public:...@@ -99,6 +103,8 @@ public:
99 size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }103 size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
100104
101 void writeTo(uint8_t *Buf) const override {105 void writeTo(uint8_t *Buf) const override {
106 memset(Buf + OutputSectionOff, 0, getSize());
107
102 auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);108 auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
103 E->ImportLookupTableRVA = LookupTab->getRVA();109 E->ImportLookupTableRVA = LookupTab->getRVA();
104 E->NameRVA = DLLName->getRVA();110 E->NameRVA = DLLName->getRVA();
...@@ -118,6 +124,10 @@ public:...@@ -118,6 +124,10 @@ public:
118 bool hasData() const override { return false; }124 bool hasData() const override { return false; }
119 size_t getSize() const override { return Size; }125 size_t getSize() const override { return Size; }
120126
127 void writeTo(uint8_t *Buf) const override {
128 memset(Buf + OutputSectionOff, 0, Size);
129 }
130
121private:131private:
122 size_t Size;132 size_t Size;
123};133};
...@@ -160,6 +170,8 @@ public:...@@ -160,6 +170,8 @@ public:
160 }170 }
161171
162 void writeTo(uint8_t *Buf) const override {172 void writeTo(uint8_t *Buf) const override {
173 memset(Buf + OutputSectionOff, 0, getSize());
174
163 auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);175 auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
164 E->Attributes = 1;176 E->Attributes = 1;
165 E->Name = DLLName->getRVA();177 E->Name = DLLName->getRVA();
...@@ -230,6 +242,36 @@ static const uint8_t ThunkARM[] = {...@@ -230,6 +242,36 @@ static const uint8_t ThunkARM[] = {
230 0x60, 0x47, // bx ip242 0x60, 0x47, // bx ip
231};243};
232244
245static const uint8_t ThunkARM64[] = {
246 0x11, 0x00, 0x00, 0x90, // adrp x17, #0 __imp_<FUNCNAME>
247 0x31, 0x02, 0x00, 0x91, // add x17, x17, #0 :lo12:__imp_<FUNCNAME>
248 0xfd, 0x7b, 0xb3, 0xa9, // stp x29, x30, [sp, #-208]!
249 0xfd, 0x03, 0x00, 0x91, // mov x29, sp
250 0xe0, 0x07, 0x01, 0xa9, // stp x0, x1, [sp, #16]
251 0xe2, 0x0f, 0x02, 0xa9, // stp x2, x3, [sp, #32]
252 0xe4, 0x17, 0x03, 0xa9, // stp x4, x5, [sp, #48]
253 0xe6, 0x1f, 0x04, 0xa9, // stp x6, x7, [sp, #64]
254 0xe0, 0x87, 0x02, 0xad, // stp q0, q1, [sp, #80]
255 0xe2, 0x8f, 0x03, 0xad, // stp q2, q3, [sp, #112]
256 0xe4, 0x97, 0x04, 0xad, // stp q4, q5, [sp, #144]
257 0xe6, 0x9f, 0x05, 0xad, // stp q6, q7, [sp, #176]
258 0xe1, 0x03, 0x11, 0xaa, // mov x1, x17
259 0x00, 0x00, 0x00, 0x90, // adrp x0, #0 DELAY_IMPORT_DESCRIPTOR
260 0x00, 0x00, 0x00, 0x91, // add x0, x0, #0 :lo12:DELAY_IMPORT_DESCRIPTOR
261 0x00, 0x00, 0x00, 0x94, // bl #0 __delayLoadHelper2
262 0xf0, 0x03, 0x00, 0xaa, // mov x16, x0
263 0xe6, 0x9f, 0x45, 0xad, // ldp q6, q7, [sp, #176]
264 0xe4, 0x97, 0x44, 0xad, // ldp q4, q5, [sp, #144]
265 0xe2, 0x8f, 0x43, 0xad, // ldp q2, q3, [sp, #112]
266 0xe0, 0x87, 0x42, 0xad, // ldp q0, q1, [sp, #80]
267 0xe6, 0x1f, 0x44, 0xa9, // ldp x6, x7, [sp, #64]
268 0xe4, 0x17, 0x43, 0xa9, // ldp x4, x5, [sp, #48]
269 0xe2, 0x0f, 0x42, 0xa9, // ldp x2, x3, [sp, #32]
270 0xe0, 0x07, 0x41, 0xa9, // ldp x0, x1, [sp, #16]
271 0xfd, 0x7b, 0xcd, 0xa8, // ldp x29, x30, [sp], #208
272 0x00, 0x02, 0x1f, 0xd6, // br x16
273};
274
233// A chunk for the delay import thunk.275// A chunk for the delay import thunk.
234class ThunkChunkX64 : public Chunk {276class ThunkChunkX64 : public Chunk {
235public:277public:
...@@ -298,11 +340,35 @@ public:...@@ -298,11 +340,35 @@ public:
298 Defined *Helper = nullptr;340 Defined *Helper = nullptr;
299};341};
300342
343class ThunkChunkARM64 : public Chunk {
344public:
345 ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
346 : Imp(I), Desc(D), Helper(H) {}
347
348 size_t getSize() const override { return sizeof(ThunkARM64); }
349
350 void writeTo(uint8_t *Buf) const override {
351 memcpy(Buf + OutputSectionOff, ThunkARM64, sizeof(ThunkARM64));
352 applyArm64Addr(Buf + OutputSectionOff + 0, Imp->getRVA(), RVA + 0, 12);
353 applyArm64Imm(Buf + OutputSectionOff + 4, Imp->getRVA() & 0xfff, 0);
354 applyArm64Addr(Buf + OutputSectionOff + 52, Desc->getRVA(), RVA + 52, 12);
355 applyArm64Imm(Buf + OutputSectionOff + 56, Desc->getRVA() & 0xfff, 0);
356 applyArm64Branch26(Buf + OutputSectionOff + 60,
357 Helper->getRVA() - RVA - 60);
358 }
359
360 Defined *Imp = nullptr;
361 Chunk *Desc = nullptr;
362 Defined *Helper = nullptr;
363};
364
301// A chunk for the import descriptor table.365// A chunk for the import descriptor table.
302class DelayAddressChunk : public Chunk {366class DelayAddressChunk : public Chunk {
303public:367public:
304 explicit DelayAddressChunk(Chunk *C) : Thunk(C) { Alignment = ptrSize(); }368 explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
305 size_t getSize() const override { return ptrSize(); }369 Alignment = Config->Wordsize;
370 }
371 size_t getSize() const override { return Config->Wordsize; }
306372
307 void writeTo(uint8_t *Buf) const override {373 void writeTo(uint8_t *Buf) const override {
308 if (Config->is64()) {374 if (Config->is64()) {
...@@ -338,6 +404,8 @@ public:...@@ -338,6 +404,8 @@ public:
338 }404 }
339405
340 void writeTo(uint8_t *Buf) const override {406 void writeTo(uint8_t *Buf) const override {
407 memset(Buf + OutputSectionOff, 0, getSize());
408
341 auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);409 auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
342 E->NameRVA = DLLName->getRVA();410 E->NameRVA = DLLName->getRVA();
343 E->OrdinalBase = 0;411 E->OrdinalBase = 0;
...@@ -362,6 +430,8 @@ public:...@@ -362,6 +430,8 @@ public:
362 size_t getSize() const override { return Size * 4; }430 size_t getSize() const override { return Size * 4; }
363431
364 void writeTo(uint8_t *Buf) const override {432 void writeTo(uint8_t *Buf) const override {
433 memset(Buf + OutputSectionOff, 0, getSize());
434
365 for (const Export &E : Config->Exports) {435 for (const Export &E : Config->Exports) {
366 uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;436 uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
367 uint32_t Bit = 0;437 uint32_t Bit = 0;
...@@ -418,30 +488,6 @@ private:...@@ -418,30 +488,6 @@ private:
418488
419} // anonymous namespace489} // anonymous namespace
420490
421uint64_t IdataContents::getDirSize() {
422 return Dirs.size() * sizeof(ImportDirectoryTableEntry);
423}
424
425uint64_t IdataContents::getIATSize() {
426 return Addresses.size() * ptrSize();
427}
428
429// Returns a list of .idata contents.
430// See Microsoft PE/COFF spec 5.4 for details.
431std::vector<Chunk *> IdataContents::getChunks() {
432 create();
433
434 // The loader assumes a specific order of data.
435 // Add each type in the correct order.
436 std::vector<Chunk *> V;
437 V.insert(V.end(), Dirs.begin(), Dirs.end());
438 V.insert(V.end(), Lookups.begin(), Lookups.end());
439 V.insert(V.end(), Addresses.begin(), Addresses.end());
440 V.insert(V.end(), Hints.begin(), Hints.end());
441 V.insert(V.end(), DLLNames.begin(), DLLNames.end());
442 return V;
443}
444
445void IdataContents::create() {491void IdataContents::create() {
446 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);492 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
447493
...@@ -465,8 +511,8 @@ void IdataContents::create() {...@@ -465,8 +511,8 @@ void IdataContents::create() {
465 Hints.push_back(C);511 Hints.push_back(C);
466 }512 }
467 // Terminate with null values.513 // Terminate with null values.
468 Lookups.push_back(make<NullChunk>(ptrSize()));514 Lookups.push_back(make<NullChunk>(Config->Wordsize));
469 Addresses.push_back(make<NullChunk>(ptrSize()));515 Addresses.push_back(make<NullChunk>(Config->Wordsize));
470516
471 for (int I = 0, E = Syms.size(); I < E; ++I)517 for (int I = 0, E = Syms.size(); I < E; ++I)
472 Syms[I]->setLocation(Addresses[Base + I]);518 Syms[I]->setLocation(Addresses[Base + I]);
...@@ -555,6 +601,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {...@@ -555,6 +601,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
555 return make<ThunkChunkX86>(S, Dir, Helper);601 return make<ThunkChunkX86>(S, Dir, Helper);
556 case ARMNT:602 case ARMNT:
557 return make<ThunkChunkARM>(S, Dir, Helper);603 return make<ThunkChunkARM>(S, Dir, Helper);
604 case ARM64:
605 return make<ThunkChunkARM64>(S, Dir, Helper);
558 default:606 default:
559 llvm_unreachable("unsupported machine type");607 llvm_unreachable("unsupported machine type");
560 }608 }
deps/lld/COFF/DLL.h+1-8
...@@ -19,19 +19,12 @@ namespace coff {...@@ -19,19 +19,12 @@ namespace coff {
19// Windows-specific.19// Windows-specific.
20// IdataContents creates all chunks for the DLL import table.20// IdataContents creates all chunks for the DLL import table.
21// You are supposed to call add() to add symbols and then21// You are supposed to call add() to add symbols and then
22// call getChunks() to get a list of chunks.22// call create() to populate the chunk vectors.
23class IdataContents {23class IdataContents {
24public:24public:
25 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }25 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
26 bool empty() { return Imports.empty(); }26 bool empty() { return Imports.empty(); }
27 std::vector<Chunk *> getChunks();
2827
29 uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
30 uint64_t getDirSize();
31 uint64_t getIATRVA() { return Addresses[0]->getRVA(); }
32 uint64_t getIATSize();
33
34private:
35 void create();28 void create();
3629
37 std::vector<DefinedImportData *> Imports;30 std::vector<DefinedImportData *> Imports;
deps/lld/COFF/Driver.cpp+276-185
...@@ -32,6 +32,7 @@...@@ -32,6 +32,7 @@
32#include "llvm/Option/ArgList.h"32#include "llvm/Option/ArgList.h"
33#include "llvm/Option/Option.h"33#include "llvm/Option/Option.h"
34#include "llvm/Support/Debug.h"34#include "llvm/Support/Debug.h"
35#include "llvm/Support/LEB128.h"
35#include "llvm/Support/Path.h"36#include "llvm/Support/Path.h"
36#include "llvm/Support/Process.h"37#include "llvm/Support/Process.h"
37#include "llvm/Support/TarWriter.h"38#include "llvm/Support/TarWriter.h"
...@@ -56,7 +57,7 @@ Configuration *Config;...@@ -56,7 +57,7 @@ Configuration *Config;
56LinkerDriver *Driver;57LinkerDriver *Driver;
5758
58bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {59bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
59 errorHandler().LogName = sys::path::filename(Args[0]);60 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
60 errorHandler().ErrorOS = &Diag;61 errorHandler().ErrorOS = &Diag;
61 errorHandler().ColorDiagnostics = Diag.has_colors();62 errorHandler().ColorDiagnostics = Diag.has_colors();
62 errorHandler().ErrorLimitExceededMsg =63 errorHandler().ErrorLimitExceededMsg =
...@@ -370,13 +371,30 @@ Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {...@@ -370,13 +371,30 @@ Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
370 return Path;371 return Path;
371}372}
372373
374// MinGW specific. If an embedded directive specified to link to
375// foo.lib, but it isn't found, try libfoo.a instead.
376StringRef LinkerDriver::doFindLibMinGW(StringRef Filename) {
377 if (Filename.contains('/') || Filename.contains('\\'))
378 return Filename;
379
380 SmallString<128> S = Filename;
381 sys::path::replace_extension(S, ".a");
382 StringRef LibName = Saver.save("lib" + S.str());
383 return doFindFile(LibName);
384}
385
373// Find library file from search path.386// Find library file from search path.
374StringRef LinkerDriver::doFindLib(StringRef Filename) {387StringRef LinkerDriver::doFindLib(StringRef Filename) {
375 // Add ".lib" to Filename if that has no file extension.388 // Add ".lib" to Filename if that has no file extension.
376 bool HasExt = Filename.contains('.');389 bool HasExt = Filename.contains('.');
377 if (!HasExt)390 if (!HasExt)
378 Filename = Saver.save(Filename + ".lib");391 Filename = Saver.save(Filename + ".lib");
379 return doFindFile(Filename);392 StringRef Ret = doFindFile(Filename);
393 // For MinGW, if the find above didn't turn up anything, try
394 // looking for a MinGW formatted library name.
395 if (Config->MinGW && Ret == Filename)
396 return doFindLibMinGW(Filename);
397 return Ret;
380}398}
381399
382// Resolves a library path. /nodefaultlib options are taken into400// Resolves a library path. /nodefaultlib options are taken into
...@@ -429,29 +447,48 @@ StringRef LinkerDriver::findDefaultEntry() {...@@ -429,29 +447,48 @@ StringRef LinkerDriver::findDefaultEntry() {
429 assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&447 assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
430 "must handle /subsystem before calling this");448 "must handle /subsystem before calling this");
431449
432 // As a special case, if /nodefaultlib is given, we directly look for an450 if (Config->MinGW)
433 // entry point. This is because, if no default library is linked, users451 return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
434 // need to define an entry point instead of a "main".452 ? "WinMainCRTStartup"
435 bool FindMain = !Config->NoDefaultLibAll;453 : "mainCRTStartup");
454
436 if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {455 if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
437 if (findUnderscoreMangle(FindMain ? "WinMain" : "WinMainCRTStartup"))456 if (findUnderscoreMangle("wWinMain")) {
438 return mangle("WinMainCRTStartup");457 if (!findUnderscoreMangle("WinMain"))
439 if (findUnderscoreMangle(FindMain ? "wWinMain" : "wWinMainCRTStartup"))458 return mangle("wWinMainCRTStartup");
440 return mangle("wWinMainCRTStartup");459 warn("found both wWinMain and WinMain; using latter");
441 }460 }
442 if (findUnderscoreMangle(FindMain ? "main" : "mainCRTStartup"))461 return mangle("WinMainCRTStartup");
443 return mangle("mainCRTStartup");462 }
444 if (findUnderscoreMangle(FindMain ? "wmain" : "wmainCRTStartup"))463 if (findUnderscoreMangle("wmain")) {
445 return mangle("wmainCRTStartup");464 if (!findUnderscoreMangle("main"))
446 return "";465 return mangle("wmainCRTStartup");
466 warn("found both wmain and main; using latter");
467 }
468 return mangle("mainCRTStartup");
447}469}
448470
449WindowsSubsystem LinkerDriver::inferSubsystem() {471WindowsSubsystem LinkerDriver::inferSubsystem() {
450 if (Config->DLL)472 if (Config->DLL)
451 return IMAGE_SUBSYSTEM_WINDOWS_GUI;473 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
452 if (findUnderscoreMangle("main") || findUnderscoreMangle("wmain"))474 if (Config->MinGW)
475 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
476 // Note that link.exe infers the subsystem from the presence of these
477 // functions even if /entry: or /nodefaultlib are passed which causes them
478 // to not be called.
479 bool HaveMain = findUnderscoreMangle("main");
480 bool HaveWMain = findUnderscoreMangle("wmain");
481 bool HaveWinMain = findUnderscoreMangle("WinMain");
482 bool HaveWWinMain = findUnderscoreMangle("wWinMain");
483 if (HaveMain || HaveWMain) {
484 if (HaveWinMain || HaveWWinMain) {
485 warn(std::string("found ") + (HaveMain ? "main" : "wmain") + " and " +
486 (HaveWinMain ? "WinMain" : "wWinMain") +
487 "; defaulting to /subsystem:console");
488 }
453 return IMAGE_SUBSYSTEM_WINDOWS_CUI;489 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
454 if (findUnderscoreMangle("WinMain") || findUnderscoreMangle("wWinMain"))490 }
491 if (HaveWinMain || HaveWWinMain)
455 return IMAGE_SUBSYSTEM_WINDOWS_GUI;492 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
456 return IMAGE_SUBSYSTEM_UNKNOWN;493 return IMAGE_SUBSYSTEM_UNKNOWN;
457}494}
...@@ -497,26 +534,65 @@ static std::string createResponseFile(const opt::InputArgList &Args,...@@ -497,26 +534,65 @@ static std::string createResponseFile(const opt::InputArgList &Args,
497 return Data.str();534 return Data.str();
498}535}
499536
500static unsigned getDefaultDebugType(const opt::InputArgList &Args) {537enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab };
501 unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);538
539static DebugKind parseDebugKind(const opt::InputArgList &Args) {
540 auto *A = Args.getLastArg(OPT_debug, OPT_debug_opt);
541 if (!A)
542 return DebugKind::None;
543 if (A->getNumValues() == 0)
544 return DebugKind::Full;
545
546 DebugKind Debug = StringSwitch<DebugKind>(A->getValue())
547 .CaseLower("none", DebugKind::None)
548 .CaseLower("full", DebugKind::Full)
549 .CaseLower("fastlink", DebugKind::FastLink)
550 // LLD extensions
551 .CaseLower("ghash", DebugKind::GHash)
552 .CaseLower("dwarf", DebugKind::Dwarf)
553 .CaseLower("symtab", DebugKind::Symtab)
554 .Default(DebugKind::Unknown);
555
556 if (Debug == DebugKind::FastLink) {
557 warn("/debug:fastlink unsupported; using /debug:full");
558 return DebugKind::Full;
559 }
560 if (Debug == DebugKind::Unknown) {
561 error("/debug: unknown option: " + Twine(A->getValue()));
562 return DebugKind::None;
563 }
564 return Debug;
565}
566
567static unsigned parseDebugTypes(const opt::InputArgList &Args) {
568 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
569
570 if (auto *A = Args.getLastArg(OPT_debugtype)) {
571 SmallVector<StringRef, 3> Types;
572 A->getSpelling().split(Types, ',', /*KeepEmpty=*/false);
573
574 for (StringRef Type : Types) {
575 unsigned V = StringSwitch<unsigned>(Type.lower())
576 .Case("cv", static_cast<unsigned>(DebugType::CV))
577 .Case("pdata", static_cast<unsigned>(DebugType::PData))
578 .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
579 .Default(0);
580 if (V == 0) {
581 warn("/debugtype: unknown option: " + Twine(A->getValue()));
582 continue;
583 }
584 DebugTypes |= V;
585 }
586 return DebugTypes;
587 }
588
589 // Default debug types
590 DebugTypes = static_cast<unsigned>(DebugType::CV);
502 if (Args.hasArg(OPT_driver))591 if (Args.hasArg(OPT_driver))
503 DebugTypes |= static_cast<unsigned>(DebugType::PData);592 DebugTypes |= static_cast<unsigned>(DebugType::PData);
504 if (Args.hasArg(OPT_profile))593 if (Args.hasArg(OPT_profile))
505 DebugTypes |= static_cast<unsigned>(DebugType::Fixup);594 DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
506 return DebugTypes;
507}
508
509static unsigned parseDebugType(StringRef Arg) {
510 SmallVector<StringRef, 3> Types;
511 Arg.split(Types, ',', /*KeepEmpty=*/false);
512595
513 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
514 for (StringRef Type : Types)
515 DebugTypes |= StringSwitch<unsigned>(Type.lower())
516 .Case("cv", static_cast<unsigned>(DebugType::CV))
517 .Case("pdata", static_cast<unsigned>(DebugType::PData))
518 .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
519 .Default(0);
520 return DebugTypes;596 return DebugTypes;
521}597}
522598
...@@ -676,131 +752,6 @@ static void parseModuleDefs(StringRef Path) {...@@ -676,131 +752,6 @@ static void parseModuleDefs(StringRef Path) {
676 }752 }
677}753}
678754
679// A helper function for filterBitcodeFiles.
680static bool needsRebuilding(MemoryBufferRef MB) {
681 // The MSVC linker doesn't support thin archives, so if it's a thin
682 // archive, we always need to rebuild it.
683 std::unique_ptr<Archive> File =
684 CHECK(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier());
685 if (File->isThin())
686 return true;
687
688 // Returns true if the archive contains at least one bitcode file.
689 for (MemoryBufferRef Member : getArchiveMembers(File.get()))
690 if (identify_magic(Member.getBuffer()) == file_magic::bitcode)
691 return true;
692 return false;
693}
694
695// Opens a given path as an archive file and removes bitcode files
696// from them if exists. This function is to appease the MSVC linker as
697// their linker doesn't like archive files containing non-native
698// object files.
699//
700// If a given archive doesn't contain bitcode files, the archive path
701// is returned as-is. Otherwise, a new temporary file is created and
702// its path is returned.
703static Optional<std::string>
704filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) {
705 std::unique_ptr<MemoryBuffer> MB = CHECK(
706 MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
707 MemoryBufferRef MBRef = MB->getMemBufferRef();
708 file_magic Magic = identify_magic(MBRef.getBuffer());
709
710 if (Magic == file_magic::bitcode)
711 return None;
712 if (Magic != file_magic::archive)
713 return Path.str();
714 if (!needsRebuilding(MBRef))
715 return Path.str();
716
717 std::unique_ptr<Archive> File =
718 CHECK(Archive::create(MBRef),
719 MBRef.getBufferIdentifier() + ": failed to parse archive");
720
721 std::vector<NewArchiveMember> New;
722 for (MemoryBufferRef Member : getArchiveMembers(File.get()))
723 if (identify_magic(Member.getBuffer()) != file_magic::bitcode)
724 New.emplace_back(Member);
725
726 if (New.empty())
727 return None;
728
729 log("Creating a temporary archive for " + Path + " to remove bitcode files");
730
731 SmallString<128> S;
732 if (std::error_code EC = sys::fs::createTemporaryFile(
733 "lld-" + sys::path::stem(Path), ".lib", S))
734 fatal("cannot create a temporary file: " + EC.message());
735 std::string Temp = S.str();
736 TemporaryFiles.push_back(Temp);
737
738 Error E =
739 llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU,
740 /*Deterministics=*/true,
741 /*Thin=*/false);
742 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
743 error("failed to create a new archive " + S.str() + ": " + EI.message());
744 });
745 return Temp;
746}
747
748// Create response file contents and invoke the MSVC linker.
749void LinkerDriver::invokeMSVC(opt::InputArgList &Args) {
750 std::string Rsp = "/nologo\n";
751 std::vector<std::string> Temps;
752
753 // Write out archive members that we used in symbol resolution and pass these
754 // to MSVC before any archives, so that MSVC uses the same objects to satisfy
755 // references.
756 for (ObjFile *Obj : ObjFile::Instances) {
757 if (Obj->ParentName.empty())
758 continue;
759 SmallString<128> S;
760 int Fd;
761 if (auto EC = sys::fs::createTemporaryFile(
762 "lld-" + sys::path::filename(Obj->ParentName), ".obj", Fd, S))
763 fatal("cannot create a temporary file: " + EC.message());
764 raw_fd_ostream OS(Fd, /*shouldClose*/ true);
765 OS << Obj->MB.getBuffer();
766 Temps.push_back(S.str());
767 Rsp += quote(S) + "\n";
768 }
769
770 for (auto *Arg : Args) {
771 switch (Arg->getOption().getID()) {
772 case OPT_linkrepro:
773 case OPT_lldmap:
774 case OPT_lldmap_file:
775 case OPT_lldsavetemps:
776 case OPT_msvclto:
777 // LLD-specific options are stripped.
778 break;
779 case OPT_opt:
780 if (!StringRef(Arg->getValue()).startswith("lld"))
781 Rsp += toString(*Arg) + " ";
782 break;
783 case OPT_INPUT: {
784 if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
785 if (Optional<std::string> S = filterBitcodeFiles(*Path, Temps))
786 Rsp += quote(*S) + "\n";
787 continue;
788 }
789 Rsp += quote(Arg->getValue()) + "\n";
790 break;
791 }
792 default:
793 Rsp += toString(*Arg) + "\n";
794 }
795 }
796
797 std::vector<StringRef> ObjFiles = Symtab->compileBitcodeFiles();
798 runMSVCLinker(Rsp, ObjFiles);
799
800 for (StringRef Path : Temps)
801 sys::fs::remove(Path);
802}
803
804void LinkerDriver::enqueueTask(std::function<void()> Task) {755void LinkerDriver::enqueueTask(std::function<void()> Task) {
805 TaskQueue.push_back(std::move(Task));756 TaskQueue.push_back(std::move(Task));
806}757}
...@@ -856,6 +807,97 @@ static void parseOrderFile(StringRef Arg) {...@@ -856,6 +807,97 @@ static void parseOrderFile(StringRef Arg) {
856 }807 }
857}808}
858809
810static void markAddrsig(Symbol *S) {
811 if (auto *D = dyn_cast_or_null<Defined>(S))
812 if (Chunk *C = D->getChunk())
813 C->KeepUnique = true;
814}
815
816static void findKeepUniqueSections() {
817 // Exported symbols could be address-significant in other executables or DSOs,
818 // so we conservatively mark them as address-significant.
819 for (Export &R : Config->Exports)
820 markAddrsig(R.Sym);
821
822 // Visit the address-significance table in each object file and mark each
823 // referenced symbol as address-significant.
824 for (ObjFile *Obj : ObjFile::Instances) {
825 ArrayRef<Symbol *> Syms = Obj->getSymbols();
826 if (Obj->AddrsigSec) {
827 ArrayRef<uint8_t> Contents;
828 Obj->getCOFFObj()->getSectionContents(Obj->AddrsigSec, Contents);
829 const uint8_t *Cur = Contents.begin();
830 while (Cur != Contents.end()) {
831 unsigned Size;
832 const char *Err;
833 uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
834 if (Err)
835 fatal(toString(Obj) + ": could not decode addrsig section: " + Err);
836 if (SymIndex >= Syms.size())
837 fatal(toString(Obj) + ": invalid symbol index in addrsig section");
838 markAddrsig(Syms[SymIndex]);
839 Cur += Size;
840 }
841 } else {
842 // If an object file does not have an address-significance table,
843 // conservatively mark all of its symbols as address-significant.
844 for (Symbol *S : Syms)
845 markAddrsig(S);
846 }
847 }
848}
849
850// link.exe replaces each %foo% in AltPath with the contents of environment
851// variable foo, and adds the two magic env vars _PDB (expands to the basename
852// of pdb's output path) and _EXT (expands to the extension of the output
853// binary).
854// lld only supports %_PDB% and %_EXT% and warns on references to all other env
855// vars.
856static void parsePDBAltPath(StringRef AltPath) {
857 SmallString<128> Buf;
858 StringRef PDBBasename =
859 sys::path::filename(Config->PDBPath, sys::path::Style::windows);
860 StringRef BinaryExtension =
861 sys::path::extension(Config->OutputFile, sys::path::Style::windows);
862 if (!BinaryExtension.empty())
863 BinaryExtension = BinaryExtension.substr(1); // %_EXT% does not include '.'.
864
865 // Invariant:
866 // +--------- Cursor ('a...' might be the empty string).
867 // | +----- FirstMark
868 // | | +- SecondMark
869 // v v v
870 // a...%...%...
871 size_t Cursor = 0;
872 while (Cursor < AltPath.size()) {
873 size_t FirstMark, SecondMark;
874 if ((FirstMark = AltPath.find('%', Cursor)) == StringRef::npos ||
875 (SecondMark = AltPath.find('%', FirstMark + 1)) == StringRef::npos) {
876 // Didn't find another full fragment, treat rest of string as literal.
877 Buf.append(AltPath.substr(Cursor));
878 break;
879 }
880
881 // Found a full fragment. Append text in front of first %, and interpret
882 // text between first and second % as variable name.
883 Buf.append(AltPath.substr(Cursor, FirstMark - Cursor));
884 StringRef Var = AltPath.substr(FirstMark, SecondMark - FirstMark + 1);
885 if (Var.equals_lower("%_pdb%"))
886 Buf.append(PDBBasename);
887 else if (Var.equals_lower("%_ext%"))
888 Buf.append(BinaryExtension);
889 else {
890 warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " +
891 Var + " as literal");
892 Buf.append(Var);
893 }
894
895 Cursor = SecondMark + 1;
896 }
897
898 Config->PDBAltPath = Buf;
899}
900
859void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {901void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
860 // If the first command line argument is "/lib", link.exe acts like lib.exe.902 // If the first command line argument is "/lib", link.exe acts like lib.exe.
861 // We call our own implementation of lib.exe that understands bitcode files.903 // We call our own implementation of lib.exe that understands bitcode files.
...@@ -944,11 +986,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -944,11 +986,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
944986
945 // Handle /ignore987 // Handle /ignore
946 for (auto *Arg : Args.filtered(OPT_ignore)) {988 for (auto *Arg : Args.filtered(OPT_ignore)) {
947 if (StringRef(Arg->getValue()) == "4037")989 SmallVector<StringRef, 8> Vec;
948 Config->WarnMissingOrderSymbol = false;990 StringRef(Arg->getValue()).split(Vec, ',');
949 else if (StringRef(Arg->getValue()) == "4217")991 for (StringRef S : Vec) {
950 Config->WarnLocallyDefinedImported = false;992 if (S == "4037")
951 // Other warning numbers are ignored.993 Config->WarnMissingOrderSymbol = false;
994 else if (S == "4099")
995 Config->WarnDebugInfoUnusable = false;
996 else if (S == "4217")
997 Config->WarnLocallyDefinedImported = false;
998 // Other warning numbers are ignored.
999 }
952 }1000 }
9531001
954 // Handle /out1002 // Handle /out
...@@ -962,20 +1010,26 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -962,20 +1010,26 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
9621010
963 // Handle /force or /force:unresolved1011 // Handle /force or /force:unresolved
964 if (Args.hasArg(OPT_force, OPT_force_unresolved))1012 if (Args.hasArg(OPT_force, OPT_force_unresolved))
965 Config->Force = true;1013 Config->ForceUnresolved = true;
1014
1015 // Handle /force or /force:multiple
1016 if (Args.hasArg(OPT_force, OPT_force_multiple))
1017 Config->ForceMultiple = true;
9661018
967 // Handle /debug1019 // Handle /debug
968 if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) {1020 DebugKind Debug = parseDebugKind(Args);
1021 if (Debug == DebugKind::Full || Debug == DebugKind::Dwarf ||
1022 Debug == DebugKind::GHash) {
969 Config->Debug = true;1023 Config->Debug = true;
970 Config->Incremental = true;1024 Config->Incremental = true;
971 if (auto *Arg = Args.getLastArg(OPT_debugtype))
972 Config->DebugTypes = parseDebugType(Arg->getValue());
973 else
974 Config->DebugTypes = getDefaultDebugType(Args);
975 }1025 }
9761026
1027 // Handle /debugtype
1028 Config->DebugTypes = parseDebugTypes(Args);
1029
977 // Handle /pdb1030 // Handle /pdb
978 bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash);1031 bool ShouldCreatePDB =
1032 (Debug == DebugKind::Full || Debug == DebugKind::GHash);
979 if (ShouldCreatePDB) {1033 if (ShouldCreatePDB) {
980 if (auto *Arg = Args.getLastArg(OPT_pdb))1034 if (auto *Arg = Args.getLastArg(OPT_pdb))
981 Config->PDBPath = Arg->getValue();1035 Config->PDBPath = Arg->getValue();
...@@ -1096,7 +1150,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1096,7 +1150,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1096 Config->Implib = Arg->getValue();1150 Config->Implib = Arg->getValue();
10971151
1098 // Handle /opt.1152 // Handle /opt.
1099 bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile);1153 bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile);
1100 unsigned ICFLevel =1154 unsigned ICFLevel =
1101 Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on1155 Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
1102 unsigned TailMerge = 1;1156 unsigned TailMerge = 1;
...@@ -1181,6 +1235,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1181,6 +1235,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1181 parseMerge(".xdata=.rdata");1235 parseMerge(".xdata=.rdata");
1182 parseMerge(".bss=.data");1236 parseMerge(".bss=.data");
11831237
1238 if (Config->MinGW) {
1239 parseMerge(".ctors=.rdata");
1240 parseMerge(".dtors=.rdata");
1241 parseMerge(".CRT=.rdata");
1242 }
1243
1184 // Handle /section1244 // Handle /section
1185 for (auto *Arg : Args.filtered(OPT_section))1245 for (auto *Arg : Args.filtered(OPT_section))
1186 parseSection(Arg->getValue());1246 parseSection(Arg->getValue());
...@@ -1234,9 +1294,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1234,9 +1294,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1234 Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);1294 Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
1235 Config->TerminalServerAware =1295 Config->TerminalServerAware =
1236 !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);1296 !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
1237 Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf);1297 Config->DebugDwarf = Debug == DebugKind::Dwarf;
1238 Config->DebugGHashes = Args.hasArg(OPT_debug_ghash);1298 Config->DebugGHashes = Debug == DebugKind::GHash;
1239 Config->DebugSymtab = Args.hasArg(OPT_debug_symtab);1299 Config->DebugSymtab = Debug == DebugKind::Symtab;
12401300
1241 Config->MapFile = getMapFile(Args);1301 Config->MapFile = getMapFile(Args);
12421302
...@@ -1266,10 +1326,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1266,10 +1326,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1266 return;1326 return;
12671327
1268 std::set<sys::fs::UniqueID> WholeArchives;1328 std::set<sys::fs::UniqueID> WholeArchives;
1269 for (auto *Arg : Args.filtered(OPT_wholearchive_file))1329 AutoExporter Exporter;
1270 if (Optional<StringRef> Path = doFindFile(Arg->getValue()))1330 for (auto *Arg : Args.filtered(OPT_wholearchive_file)) {
1331 if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
1271 if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))1332 if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))
1272 WholeArchives.insert(*ID);1333 WholeArchives.insert(*ID);
1334 Exporter.addWholeArchive(*Path);
1335 }
1336 }
12731337
1274 // A predicate returning true if a given path is an argument for1338 // A predicate returning true if a given path is an argument for
1275 // /wholearchive:, or /wholearchive is enabled globally.1339 // /wholearchive:, or /wholearchive is enabled globally.
...@@ -1300,12 +1364,16 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1300,12 +1364,16 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1300 // Read all input files given via the command line.1364 // Read all input files given via the command line.
1301 run();1365 run();
13021366
1367 if (errorCount())
1368 return;
1369
1303 // We should have inferred a machine type by now from the input files, but if1370 // We should have inferred a machine type by now from the input files, but if
1304 // not we assume x64.1371 // not we assume x64.
1305 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {1372 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
1306 warn("/machine is not specified. x64 is assumed");1373 warn("/machine is not specified. x64 is assumed");
1307 Config->Machine = AMD64;1374 Config->Machine = AMD64;
1308 }1375 }
1376 Config->Wordsize = Config->is64() ? 8 : 4;
13091377
1310 // Input files can be Windows resource files (.res files). We use1378 // Input files can be Windows resource files (.res files). We use
1311 // WindowsResource to convert resource files to a regular COFF file,1379 // WindowsResource to convert resource files to a regular COFF file,
...@@ -1418,6 +1486,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1418,6 +1486,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1418 // tools won't work correctly if these assumptions are not held.1486 // tools won't work correctly if these assumptions are not held.
1419 sys::fs::make_absolute(Config->PDBAltPath);1487 sys::fs::make_absolute(Config->PDBAltPath);
1420 sys::path::remove_dots(Config->PDBAltPath);1488 sys::path::remove_dots(Config->PDBAltPath);
1489 } else {
1490 // Don't do this earlier, so that Config->OutputFile is ready.
1491 parsePDBAltPath(Config->PDBAltPath);
1421 }1492 }
1422 }1493 }
14231494
...@@ -1441,6 +1512,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1441,6 +1512,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1441 // Needed for MSVC 2017 15.5 CRT.1512 // Needed for MSVC 2017 15.5 CRT.
1442 Symtab->addAbsolute(mangle("__enclave_config"), 0);1513 Symtab->addAbsolute(mangle("__enclave_config"), 0);
14431514
1515 if (Config->MinGW) {
1516 Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
1517 Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
1518 Symtab->addAbsolute(mangle("__CTOR_LIST__"), 0);
1519 Symtab->addAbsolute(mangle("__DTOR_LIST__"), 0);
1520 }
1521
1444 // This code may add new undefined symbols to the link, which may enqueue more1522 // This code may add new undefined symbols to the link, which may enqueue more
1445 // symbol resolution tasks, so we need to continue executing tasks until we1523 // symbol resolution tasks, so we need to continue executing tasks until we
1446 // converge.1524 // converge.
...@@ -1480,18 +1558,29 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1480,18 +1558,29 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1480 if (errorCount())1558 if (errorCount())
1481 return;1559 return;
14821560
1483 // If /msvclto is given, we use the MSVC linker to link LTO output files.
1484 // This is useful because MSVC link.exe can generate complete PDBs.
1485 if (Args.hasArg(OPT_msvclto)) {
1486 invokeMSVC(Args);
1487 return;
1488 }
1489
1490 // Do LTO by compiling bitcode input files to a set of native COFF files then1561 // Do LTO by compiling bitcode input files to a set of native COFF files then
1491 // link those files.1562 // link those files.
1492 Symtab->addCombinedLTOObjects();1563 Symtab->addCombinedLTOObjects();
1493 run();1564 run();
14941565
1566 if (Config->MinGW) {
1567 // Load any further object files that might be needed for doing automatic
1568 // imports.
1569 //
1570 // For cases with no automatically imported symbols, this iterates once
1571 // over the symbol table and doesn't do anything.
1572 //
1573 // For the normal case with a few automatically imported symbols, this
1574 // should only need to be run once, since each new object file imported
1575 // is an import library and wouldn't add any new undefined references,
1576 // but there's nothing stopping the __imp_ symbols from coming from a
1577 // normal object file as well (although that won't be used for the
1578 // actual autoimport later on). If this pass adds new undefined references,
1579 // we won't iterate further to resolve them.
1580 Symtab->loadMinGWAutomaticImports();
1581 run();
1582 }
1583
1495 // Make sure we have resolved all symbols.1584 // Make sure we have resolved all symbols.
1496 Symtab->reportRemainingUndefines();1585 Symtab->reportRemainingUndefines();
1497 if (errorCount())1586 if (errorCount())
...@@ -1510,7 +1599,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1510,7 +1599,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1510 // are chosen to be exported.1599 // are chosen to be exported.
1511 if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||1600 if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
1512 Args.hasArg(OPT_export_all_symbols))) {1601 Args.hasArg(OPT_export_all_symbols))) {
1513 AutoExporter Exporter;1602 Exporter.initSymbolExcludes();
15141603
1515 Symtab->forEachSymbol([=](Symbol *S) {1604 Symtab->forEachSymbol([=](Symbol *S) {
1516 auto *Def = dyn_cast<Defined>(S);1605 auto *Def = dyn_cast<Defined>(S);
...@@ -1574,8 +1663,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -1574,8 +1663,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
1574 markLive(Symtab->getChunks());1663 markLive(Symtab->getChunks());
15751664
1576 // Identify identical COMDAT sections to merge them.1665 // Identify identical COMDAT sections to merge them.
1577 if (Config->DoICF)1666 if (Config->DoICF) {
1667 findKeepUniqueSections();
1578 doICF(Symtab->getChunks());1668 doICF(Symtab->getChunks());
1669 }
15791670
1580 // Write the result.1671 // Write the result.
1581 writeResult();1672 writeResult();
deps/lld/COFF/Driver.h+1-2
...@@ -89,6 +89,7 @@ private:...@@ -89,6 +89,7 @@ private:
89 Optional<StringRef> findLib(StringRef Filename);89 Optional<StringRef> findLib(StringRef Filename);
90 StringRef doFindFile(StringRef Filename);90 StringRef doFindFile(StringRef Filename);
91 StringRef doFindLib(StringRef Filename);91 StringRef doFindLib(StringRef Filename);
92 StringRef doFindLibMinGW(StringRef Filename);
9293
93 // Parses LIB environment which contains a list of search paths.94 // Parses LIB environment which contains a list of search paths.
94 void addLibSearchPaths();95 void addLibSearchPaths();
...@@ -114,8 +115,6 @@ private:...@@ -114,8 +115,6 @@ private:
114 StringRef findDefaultEntry();115 StringRef findDefaultEntry();
115 WindowsSubsystem inferSubsystem();116 WindowsSubsystem inferSubsystem();
116117
117 void invokeMSVC(llvm::opt::InputArgList &Args);
118
119 void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);118 void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);
120 void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,119 void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
121 StringRef ParentName);120 StringRef ParentName);
deps/lld/COFF/DriverUtils.cpp+3-21
...@@ -713,26 +713,6 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {...@@ -713,26 +713,6 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {
713 return MBRef;713 return MBRef;
714}714}
715715
716// Run MSVC link.exe for given in-memory object files.
717// Command line options are copied from those given to LLD.
718// This is for the /msvclto option.
719void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
720 // Write the in-memory object files to disk.
721 std::vector<TemporaryFile> Temps;
722 for (StringRef S : Objects) {
723 Temps.emplace_back("lto", "obj", S);
724 Rsp += quote(Temps.back().Path) + "\n";
725 }
726
727 log("link.exe " + Rsp);
728
729 // Run MSVC link.exe.
730 Temps.emplace_back("lto", "rsp", Rsp);
731 Executor E("link.exe");
732 E.add(Twine("@" + Temps.back().Path));
733 E.run();
734}
735
736// Create OptTable716// Create OptTable
737717
738// Create prefix string literals used in Options.td718// Create prefix string literals used in Options.td
...@@ -883,7 +863,9 @@ std::vector<const char *> ArgParser::tokenize(StringRef S) {...@@ -883,7 +863,9 @@ std::vector<const char *> ArgParser::tokenize(StringRef S) {
883}863}
884864
885void printHelp(const char *Argv0) {865void printHelp(const char *Argv0) {
886 COFFOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false);866 COFFOptTable().PrintHelp(outs(),
867 (std::string(Argv0) + " [options] file...").c_str(),
868 "LLVM Linker", false);
887}869}
888870
889} // namespace coff871} // namespace coff
deps/lld/COFF/ICF.cpp+24-7
...@@ -22,6 +22,7 @@...@@ -22,6 +22,7 @@
22#include "Chunks.h"22#include "Chunks.h"
23#include "Symbols.h"23#include "Symbols.h"
24#include "lld/Common/ErrorHandler.h"24#include "lld/Common/ErrorHandler.h"
25#include "lld/Common/Threads.h"
25#include "lld/Common/Timer.h"26#include "lld/Common/Timer.h"
26#include "llvm/ADT/Hashing.h"27#include "llvm/ADT/Hashing.h"
27#include "llvm/Support/Debug.h"28#include "llvm/Support/Debug.h"
...@@ -80,7 +81,7 @@ private:...@@ -80,7 +81,7 @@ private:
80bool ICF::isEligible(SectionChunk *C) {81bool ICF::isEligible(SectionChunk *C) {
81 // Non-comdat chunks, dead chunks, and writable chunks are not elegible.82 // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
82 bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;83 bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
83 if (!C->isCOMDAT() || !C->isLive() || Writable)84 if (!C->isCOMDAT() || !C->Live || Writable)
84 return false;85 return false;
8586
86 // Code sections are eligible.87 // Code sections are eligible.
...@@ -93,7 +94,11 @@ bool ICF::isEligible(SectionChunk *C) {...@@ -93,7 +94,11 @@ bool ICF::isEligible(SectionChunk *C) {
93 return true;94 return true;
9495
95 // So are vtables.96 // So are vtables.
96 return C->Sym && C->Sym->getName().startswith("??_7");97 if (C->Sym && C->Sym->getName().startswith("??_7"))
98 return true;
99
100 // Anything else not in an address-significance table is eligible.
101 return !C->KeepUnique;
97}102}
98103
99// Split an equivalence class into smaller classes.104// Split an equivalence class into smaller classes.
...@@ -222,10 +227,10 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {...@@ -222,10 +227,10 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
222 size_t Boundaries[NumShards + 1];227 size_t Boundaries[NumShards + 1];
223 Boundaries[0] = 0;228 Boundaries[0] = 0;
224 Boundaries[NumShards] = Chunks.size();229 Boundaries[NumShards] = Chunks.size();
225 for_each_n(parallel::par, size_t(1), NumShards, [&](size_t I) {230 parallelForEachN(1, NumShards, [&](size_t I) {
226 Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size());231 Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size());
227 });232 });
228 for_each_n(parallel::par, size_t(1), NumShards + 1, [&](size_t I) {233 parallelForEachN(1, NumShards + 1, [&](size_t I) {
229 if (Boundaries[I - 1] < Boundaries[I]) {234 if (Boundaries[I - 1] < Boundaries[I]) {
230 forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);235 forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
231 }236 }
...@@ -257,11 +262,23 @@ void ICF::run(ArrayRef<Chunk *> Vec) {...@@ -257,11 +262,23 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
257 SC->Class[0] = NextId++;262 SC->Class[0] = NextId++;
258263
259 // Initially, we use hash values to partition sections.264 // Initially, we use hash values to partition sections.
260 for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) {265 parallelForEach(Chunks, [&](SectionChunk *SC) {
261 // Set MSB to 1 to avoid collisions with non-hash classs.266 SC->Class[0] = xxHash64(SC->getContents());
262 SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31);
263 });267 });
264268
269 // Combine the hashes of the sections referenced by each section into its
270 // hash.
271 for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
272 parallelForEach(Chunks, [&](SectionChunk *SC) {
273 uint32_t Hash = SC->Class[Cnt % 2];
274 for (Symbol *B : SC->symbols())
275 if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
276 Hash += Sym->getChunk()->Class[Cnt % 2];
277 // Set MSB to 1 to avoid collisions with non-hash classs.
278 SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
279 });
280 }
281
265 // From now on, sections in Chunks are ordered so that sections in282 // From now on, sections in Chunks are ordered so that sections in
266 // the same group are consecutive in the vector.283 // the same group are consecutive in the vector.
267 std::stable_sort(Chunks.begin(), Chunks.end(),284 std::stable_sort(Chunks.begin(), Chunks.end(),
deps/lld/COFF/InputFiles.cpp+35-8
...@@ -54,8 +54,16 @@ std::vector<BitcodeFile *> BitcodeFile::Instances;...@@ -54,8 +54,16 @@ std::vector<BitcodeFile *> BitcodeFile::Instances;
54static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,54static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
55 Symbol *Source, Symbol *Target) {55 Symbol *Source, Symbol *Target) {
56 if (auto *U = dyn_cast<Undefined>(Source)) {56 if (auto *U = dyn_cast<Undefined>(Source)) {
57 if (U->WeakAlias && U->WeakAlias != Target)57 if (U->WeakAlias && U->WeakAlias != Target) {
58 // Weak aliases as produced by GCC are named in the form
59 // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
60 // of another symbol emitted near the weak symbol.
61 // Just use the definition from the first object file that defined
62 // this weak symbol.
63 if (Config->MinGW)
64 return;
58 Symtab->reportDuplicate(Source, F);65 Symtab->reportDuplicate(Source, F);
66 }
59 U->WeakAlias = Target;67 U->WeakAlias = Target;
60 }68 }
61}69}
...@@ -147,9 +155,10 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,...@@ -147,9 +155,10 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
147 const coff_aux_section_definition *Def,155 const coff_aux_section_definition *Def,
148 StringRef LeaderName) {156 StringRef LeaderName) {
149 const coff_section *Sec;157 const coff_section *Sec;
150 StringRef Name;
151 if (auto EC = COFFObj->getSection(SectionNumber, Sec))158 if (auto EC = COFFObj->getSection(SectionNumber, Sec))
152 fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());159 fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());
160
161 StringRef Name;
153 if (auto EC = COFFObj->getSectionName(Sec, Name))162 if (auto EC = COFFObj->getSectionName(Sec, Name))
154 fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +163 fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +
155 EC.message());164 EC.message());
...@@ -161,6 +170,11 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,...@@ -161,6 +170,11 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
161 return nullptr;170 return nullptr;
162 }171 }
163172
173 if (Name == ".llvm_addrsig") {
174 AddrsigSec = Sec;
175 return nullptr;
176 }
177
164 // Object files may have DWARF debug info or MS CodeView debug info178 // Object files may have DWARF debug info or MS CodeView debug info
165 // (or both).179 // (or both).
166 //180 //
...@@ -168,8 +182,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,...@@ -168,8 +182,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
168 // of the linker; they are just a data section containing relocations.182 // of the linker; they are just a data section containing relocations.
169 // We can just link them to complete debug info.183 // We can just link them to complete debug info.
170 //184 //
171 // CodeView needs a linker support. We need to interpret and debug185 // CodeView needs linker support. We need to interpret debug info,
172 // info, and then write it to a separate .pdb file.186 // and then write it to a separate .pdb file.
173187
174 // Ignore DWARF debug info unless /debug is given.188 // Ignore DWARF debug info unless /debug is given.
175 if (!Config->Debug && Name.startswith(".debug_"))189 if (!Config->Debug && Name.startswith(".debug_"))
...@@ -267,10 +281,17 @@ Symbol *ObjFile::createRegular(COFFSymbolRef Sym) {...@@ -267,10 +281,17 @@ Symbol *ObjFile::createRegular(COFFSymbolRef Sym) {
267 COFFObj->getSymbolName(Sym, Name);281 COFFObj->getSymbolName(Sym, Name);
268 if (SC)282 if (SC)
269 return Symtab->addRegular(this, Name, Sym.getGeneric(), SC);283 return Symtab->addRegular(this, Name, Sym.getGeneric(), SC);
284 // For MinGW symbols named .weak.* that point to a discarded section,
285 // don't create an Undefined symbol. If nothing ever refers to the symbol,
286 // everything should be fine. If something actually refers to the symbol
287 // (e.g. the undefined weak alias), linking will fail due to undefined
288 // references at the end.
289 if (Config->MinGW && Name.startswith(".weak."))
290 return nullptr;
270 return Symtab->addUndefined(Name, this, false);291 return Symtab->addUndefined(Name, this, false);
271 }292 }
272 if (SC)293 if (SC)
273 return make<DefinedRegular>(this, /*Name*/ "", false,294 return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
274 /*IsExternal*/ false, Sym.getGeneric(), SC);295 /*IsExternal*/ false, Sym.getGeneric(), SC);
275 return nullptr;296 return nullptr;
276}297}
...@@ -318,7 +339,7 @@ void ObjFile::initializeSymbols() {...@@ -318,7 +339,7 @@ void ObjFile::initializeSymbols() {
318339
319 for (uint32_t I : PendingIndexes) {340 for (uint32_t I : PendingIndexes) {
320 COFFSymbolRef Sym = check(COFFObj->getSymbol(I));341 COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
321 if (auto *Def = Sym.getSectionDefinition()) {342 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
322 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)343 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
323 readAssociativeDefinition(Sym, Def);344 readAssociativeDefinition(Sym, Def);
324 else if (Config->MinGW)345 else if (Config->MinGW)
...@@ -401,7 +422,7 @@ Optional<Symbol *> ObjFile::createDefined(...@@ -401,7 +422,7 @@ Optional<Symbol *> ObjFile::createDefined(
401 std::tie(Leader, Prevailing) =422 std::tie(Leader, Prevailing) =
402 Symtab->addComdat(this, GetName(), Sym.getGeneric());423 Symtab->addComdat(this, GetName(), Sym.getGeneric());
403 } else {424 } else {
404 Leader = make<DefinedRegular>(this, /*Name*/ "", false,425 Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
405 /*IsExternal*/ false, Sym.getGeneric());426 /*IsExternal*/ false, Sym.getGeneric());
406 Prevailing = true;427 Prevailing = true;
407 }428 }
...@@ -421,7 +442,7 @@ Optional<Symbol *> ObjFile::createDefined(...@@ -421,7 +442,7 @@ Optional<Symbol *> ObjFile::createDefined(
421 // leader symbol by setting the section's ComdatDefs pointer if we encounter a442 // leader symbol by setting the section's ComdatDefs pointer if we encounter a
422 // non-associative comdat.443 // non-associative comdat.
423 if (SparseChunks[SectionNumber] == PendingComdat) {444 if (SparseChunks[SectionNumber] == PendingComdat) {
424 if (auto *Def = Sym.getSectionDefinition()) {445 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
425 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)446 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
426 readAssociativeDefinition(Sym, Def);447 readAssociativeDefinition(Sym, Def);
427 else448 else
...@@ -429,8 +450,10 @@ Optional<Symbol *> ObjFile::createDefined(...@@ -429,8 +450,10 @@ Optional<Symbol *> ObjFile::createDefined(
429 }450 }
430 }451 }
431452
453 // readAssociativeDefinition() writes to SparseChunks, so need to check again.
432 if (SparseChunks[SectionNumber] == PendingComdat)454 if (SparseChunks[SectionNumber] == PendingComdat)
433 return None;455 return None;
456
434 return createRegular(Sym);457 return createRegular(Sym);
435}458}
436459
...@@ -481,6 +504,10 @@ void ImportFile::parse() {...@@ -481,6 +504,10 @@ void ImportFile::parse() {
481 ExternalName = ExtName;504 ExternalName = ExtName;
482505
483 ImpSym = Symtab->addImportData(ImpName, this);506 ImpSym = Symtab->addImportData(ImpName, this);
507 // If this was a duplicate, we logged an error but may continue;
508 // in this case, ImpSym is nullptr.
509 if (!ImpSym)
510 return;
484511
485 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)512 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
486 static_cast<void>(Symtab->addImportData(Name, this));513 static_cast<void>(Symtab->addImportData(Name, this));
deps/lld/COFF/InputFiles.h+12-1
...@@ -15,6 +15,7 @@...@@ -15,6 +15,7 @@
15#include "llvm/ADT/ArrayRef.h"15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/DenseMap.h"16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/DenseSet.h"17#include "llvm/ADT/DenseSet.h"
18#include "llvm/DebugInfo/CodeView/TypeRecord.h"
18#include "llvm/LTO/LTO.h"19#include "llvm/LTO/LTO.h"
19#include "llvm/Object/Archive.h"20#include "llvm/Object/Archive.h"
20#include "llvm/Object/COFF.h"21#include "llvm/Object/COFF.h"
...@@ -122,9 +123,12 @@ public:...@@ -122,9 +123,12 @@ public:
122 return Symbols[SymbolIndex];123 return Symbols[SymbolIndex];
123 }124 }
124125
125 // Returns the underying COFF file.126 // Returns the underlying COFF file.
126 COFFObjectFile *getCOFFObj() { return COFFObj.get(); }127 COFFObjectFile *getCOFFObj() { return COFFObj.get(); }
127128
129 // Whether the object was already merged into the final PDB or not
130 bool wasProcessedForPDB() const { return !!ModuleDBI; }
131
128 static std::vector<ObjFile *> Instances;132 static std::vector<ObjFile *> Instances;
129133
130 // Flags in the absolute @feat.00 symbol if it is present. These usually134 // Flags in the absolute @feat.00 symbol if it is present. These usually
...@@ -145,6 +149,13 @@ public:...@@ -145,6 +149,13 @@ public:
145 // if we are not producing a PDB.149 // if we are not producing a PDB.
146 llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;150 llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;
147151
152 const coff_section *AddrsigSec = nullptr;
153
154 // When using Microsoft precompiled headers, this is the PCH's key.
155 // The same key is used by both the precompiled object, and objects using the
156 // precompiled object. Any difference indicates out-of-date objects.
157 llvm::Optional<uint32_t> PCHSignature;
158
148private:159private:
149 void initializeChunks();160 void initializeChunks();
150 void initializeSymbols();161 void initializeSymbols();
deps/lld/COFF/LTO.cpp+3
...@@ -60,6 +60,9 @@ static std::unique_ptr<lto::LTO> createLTO() {...@@ -60,6 +60,9 @@ static std::unique_ptr<lto::LTO> createLTO() {
60 C.DisableVerify = true;60 C.DisableVerify = true;
61 C.DiagHandler = diagnosticHandler;61 C.DiagHandler = diagnosticHandler;
62 C.OptLevel = Config->LTOO;62 C.OptLevel = Config->LTOO;
63 C.CPU = GetCPUStr();
64 C.MAttrs = GetMAttrs();
65
63 if (Config->SaveTemps)66 if (Config->SaveTemps)
64 checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",67 checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
65 /*UseInputModulePath*/ true));68 /*UseInputModulePath*/ true));
deps/lld/COFF/MapFile.cpp+1-1
...@@ -110,7 +110,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {...@@ -110,7 +110,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
110 writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);110 writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
111 OS << Sec->Name << '\n';111 OS << Sec->Name << '\n';
112112
113 for (Chunk *C : Sec->getChunks()) {113 for (Chunk *C : Sec->Chunks) {
114 auto *SC = dyn_cast<SectionChunk>(C);114 auto *SC = dyn_cast<SectionChunk>(C);
115 if (!SC)115 if (!SC)
116 continue;116 continue;
deps/lld/COFF/MarkLive.cpp+4-4
...@@ -32,13 +32,13 @@ void markLive(ArrayRef<Chunk *> Chunks) {...@@ -32,13 +32,13 @@ void markLive(ArrayRef<Chunk *> Chunks) {
32 // COMDAT section chunks are dead by default. Add non-COMDAT chunks.32 // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
33 for (Chunk *C : Chunks)33 for (Chunk *C : Chunks)
34 if (auto *SC = dyn_cast<SectionChunk>(C))34 if (auto *SC = dyn_cast<SectionChunk>(C))
35 if (SC->isLive())35 if (SC->Live)
36 Worklist.push_back(SC);36 Worklist.push_back(SC);
3737
38 auto Enqueue = [&](SectionChunk *C) {38 auto Enqueue = [&](SectionChunk *C) {
39 if (C->isLive())39 if (C->Live)
40 return;40 return;
41 C->markLive();41 C->Live = true;
42 Worklist.push_back(C);42 Worklist.push_back(C);
43 };43 };
4444
...@@ -57,7 +57,7 @@ void markLive(ArrayRef<Chunk *> Chunks) {...@@ -57,7 +57,7 @@ void markLive(ArrayRef<Chunk *> Chunks) {
5757
58 while (!Worklist.empty()) {58 while (!Worklist.empty()) {
59 SectionChunk *SC = Worklist.pop_back_val();59 SectionChunk *SC = Worklist.pop_back_val();
60 assert(SC->isLive() && "We mark as live when pushing onto the worklist!");60 assert(SC->Live && "We mark as live when pushing onto the worklist!");
6161
62 // Mark all symbols listed in the relocation table for this section.62 // Mark all symbols listed in the relocation table for this section.
63 for (Symbol *B : SC->symbols())63 for (Symbol *B : SC->symbols())
deps/lld/COFF/MinGW.cpp+36-6
...@@ -19,7 +19,23 @@ using namespace lld::coff;...@@ -19,7 +19,23 @@ using namespace lld::coff;
19using namespace llvm;19using namespace llvm;
20using namespace llvm::COFF;20using namespace llvm::COFF;
2121
22AutoExporter::AutoExporter() {22void AutoExporter::initSymbolExcludes() {
23 ExcludeSymbolPrefixes = {
24 // Import symbols
25 "__imp_",
26 "__IMPORT_DESCRIPTOR_",
27 // Extra import symbols from GNU import libraries
28 "__nm_",
29 // C++ symbols
30 "__rtti_",
31 "__builtin_",
32 // Artifical symbols such as .refptr
33 ".",
34 };
35 ExcludeSymbolSuffixes = {
36 "_iname",
37 "_NULL_THUNK_DATA",
38 };
23 if (Config->Machine == I386) {39 if (Config->Machine == I386) {
24 ExcludeSymbols = {40 ExcludeSymbols = {
25 "__NULL_IMPORT_DESCRIPTOR",41 "__NULL_IMPORT_DESCRIPTOR",
...@@ -36,9 +52,10 @@ AutoExporter::AutoExporter() {...@@ -36,9 +52,10 @@ AutoExporter::AutoExporter() {
36 "_DllEntryPoint@12",52 "_DllEntryPoint@12",
37 "_DllMainCRTStartup@12",53 "_DllMainCRTStartup@12",
38 };54 };
55 ExcludeSymbolPrefixes.insert("__head_");
39 } else {56 } else {
40 ExcludeSymbols = {57 ExcludeSymbols = {
41 "_NULL_IMPORT_DESCRIPTOR",58 "__NULL_IMPORT_DESCRIPTOR",
42 "_pei386_runtime_relocator",59 "_pei386_runtime_relocator",
43 "do_pseudo_reloc",60 "do_pseudo_reloc",
44 "impure_ptr",61 "impure_ptr",
...@@ -52,8 +69,11 @@ AutoExporter::AutoExporter() {...@@ -52,8 +69,11 @@ AutoExporter::AutoExporter() {
52 "DllEntryPoint",69 "DllEntryPoint",
53 "DllMainCRTStartup",70 "DllMainCRTStartup",
54 };71 };
72 ExcludeSymbolPrefixes.insert("_head_");
55 }73 }
74}
5675
76AutoExporter::AutoExporter() {
57 ExcludeLibs = {77 ExcludeLibs = {
58 "libgcc",78 "libgcc",
59 "libgcc_s",79 "libgcc_s",
...@@ -64,6 +84,7 @@ AutoExporter::AutoExporter() {...@@ -64,6 +84,7 @@ AutoExporter::AutoExporter() {
64 "libsupc++",84 "libsupc++",
65 "libobjc",85 "libobjc",
66 "libgcj",86 "libgcj",
87 "libclang_rt.builtins",
67 "libclang_rt.builtins-aarch64",88 "libclang_rt.builtins-aarch64",
68 "libclang_rt.builtins-arm",89 "libclang_rt.builtins-arm",
69 "libclang_rt.builtins-i386",90 "libclang_rt.builtins-i386",
...@@ -90,6 +111,13 @@ AutoExporter::AutoExporter() {...@@ -90,6 +111,13 @@ AutoExporter::AutoExporter() {
90 };111 };
91}112}
92113
114void AutoExporter::addWholeArchive(StringRef Path) {
115 StringRef LibName = sys::path::filename(Path);
116 // Drop the file extension, to match the processing below.
117 LibName = LibName.substr(0, LibName.rfind('.'));
118 ExcludeLibs.erase(LibName);
119}
120
93bool AutoExporter::shouldExport(Defined *Sym) const {121bool AutoExporter::shouldExport(Defined *Sym) const {
94 if (!Sym || !Sym->isLive() || !Sym->getChunk())122 if (!Sym || !Sym->isLive() || !Sym->getChunk())
95 return false;123 return false;
...@@ -101,10 +129,12 @@ bool AutoExporter::shouldExport(Defined *Sym) const {...@@ -101,10 +129,12 @@ bool AutoExporter::shouldExport(Defined *Sym) const {
101 if (ExcludeSymbols.count(Sym->getName()))129 if (ExcludeSymbols.count(Sym->getName()))
102 return false;130 return false;
103131
104 // Don't export anything that looks like an import symbol (which also can be132 for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
105 // a manually defined data symbol with such a name).133 if (Sym->getName().startswith(Prefix))
106 if (Sym->getName().startswith("__imp_"))134 return false;
107 return false;135 for (StringRef Suffix : ExcludeSymbolSuffixes.keys())
136 if (Sym->getName().endswith(Suffix))
137 return false;
108138
109 // If a corresponding __imp_ symbol exists and is defined, don't export it.139 // If a corresponding __imp_ symbol exists and is defined, don't export it.
110 if (Symtab->find(("__imp_" + Sym->getName()).str()))140 if (Symtab->find(("__imp_" + Sym->getName()).str()))
deps/lld/COFF/MinGW.h+6
...@@ -23,7 +23,13 @@ class AutoExporter {...@@ -23,7 +23,13 @@ class AutoExporter {
23public:23public:
24 AutoExporter();24 AutoExporter();
2525
26 void initSymbolExcludes();
27
28 void addWholeArchive(StringRef Path);
29
26 llvm::StringSet<> ExcludeSymbols;30 llvm::StringSet<> ExcludeSymbols;
31 llvm::StringSet<> ExcludeSymbolPrefixes;
32 llvm::StringSet<> ExcludeSymbolSuffixes;
27 llvm::StringSet<> ExcludeLibs;33 llvm::StringSet<> ExcludeLibs;
28 llvm::StringSet<> ExcludeObjects;34 llvm::StringSet<> ExcludeObjects;
2935
deps/lld/COFF/Options.td+22-15
...@@ -66,13 +66,18 @@ def wholearchive_file : P<"wholearchive", "Include all object files from this ar...@@ -66,13 +66,18 @@ def wholearchive_file : P<"wholearchive", "Include all object files from this ar
6666
67def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;67def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
6868
69def manifest : F<"manifest">;69def manifest : F<"manifest">, HelpText<"Create .manifest file">;
70def manifest_colon : P<"manifest", "Create manifest file">;70def manifest_colon : P<
71 "manifest",
72 "NO disables manifest output; EMBED[,ID=#] embeds manifest as resource in the image">;
71def manifestuac : P<"manifestuac", "User access control">;73def manifestuac : P<"manifestuac", "User access control">;
72def manifestfile : P<"manifestfile", "Manifest file path">;74def manifestfile : P<"manifestfile", "Manifest output path, with /manifest">;
73def manifestdependency : P<"manifestdependency",75def manifestdependency : P<
74 "Attributes for <dependency> in manifest file">;76 "manifestdependency",
75def manifestinput : P<"manifestinput", "Specify manifest file">;77 "Attributes for <dependency> element in manifest file; implies /manifest">;
78def manifestinput : P<
79 "manifestinput",
80 "Additional manifest inputs; only valid with /manifest:embed">;
7681
77// We cannot use multiclass P because class name "incl" is different82// We cannot use multiclass P because class name "incl" is different
78// from its command line option name. We do this because "include" is83// from its command line option name. We do this because "include" is
...@@ -85,22 +90,28 @@ def deffile : Joined<["/", "-"], "def:">,...@@ -85,22 +90,28 @@ def deffile : Joined<["/", "-"], "def:">,
85 HelpText<"Use module-definition file">;90 HelpText<"Use module-definition file">;
8691
87def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;92def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
88def debug_full : F<"debug:full">, Alias<debug>;93def debug_opt : P<"debug", "Embed a symbol table in the image with option">;
89def debugtype : P<"debugtype", "Debug Info Options">;94def debugtype : P<"debugtype", "Debug Info Options">;
90def dll : F<"dll">, HelpText<"Create a DLL">;95def dll : F<"dll">, HelpText<"Create a DLL">;
91def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;96def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
92def nodefaultlib_all : F<"nodefaultlib">;97def nodefaultlib_all : F<"nodefaultlib">,
93def noentry : F<"noentry">;98 HelpText<"Remove all default libraries">;
99def noentry : F<"noentry">,
100 HelpText<"Don't add reference to DllMainCRTStartup; only valid with /dll">;
94def profile : F<"profile">;101def profile : F<"profile">;
95def repro : F<"Brepro">, HelpText<"Use a hash of the executable as the PE header timestamp">;102def repro : F<"Brepro">,
103 HelpText<"Use a hash of the executable as the PE header timestamp">;
96def swaprun_cd : F<"swaprun:cd">;104def swaprun_cd : F<"swaprun:cd">;
97def swaprun_net : F<"swaprun:net">;105def swaprun_net : F<"swaprun:net">;
98def verbose : F<"verbose">;106def verbose : F<"verbose">;
99def wholearchive_flag : F<"wholearchive">;107def wholearchive_flag : F<"wholearchive">;
100108
101def force : F<"force">,109def force : F<"force">,
110 HelpText<"Allow undefined and multiply defined symbols when creating executables">;
111def force_unresolved : F<"force:unresolved">,
102 HelpText<"Allow undefined symbols when creating executables">;112 HelpText<"Allow undefined symbols when creating executables">;
103def force_unresolved : F<"force:unresolved">;113def force_multiple : F<"force:multiple">,
114 HelpText<"Allow multiply defined symbols when creating executables">;
104defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;115defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
105116
106defm allowbind : B<"allowbind", "Enable DLL binding (default)",117defm allowbind : B<"allowbind", "Enable DLL binding (default)",
...@@ -139,13 +150,9 @@ def help : F<"help">;...@@ -139,13 +150,9 @@ def help : F<"help">;
139def help_q : Flag<["/?", "-?"], "">, Alias<help>;150def help_q : Flag<["/?", "-?"], "">, Alias<help>;
140151
141// LLD extensions152// LLD extensions
142def debug_ghash : F<"debug:ghash">;
143def debug_dwarf : F<"debug:dwarf">;
144def debug_symtab : F<"debug:symtab">;
145def export_all_symbols : F<"export-all-symbols">;153def export_all_symbols : F<"export-all-symbols">;
146def kill_at : F<"kill-at">;154def kill_at : F<"kill-at">;
147def lldmingw : F<"lldmingw">;155def lldmingw : F<"lldmingw">;
148def msvclto : F<"msvclto">;
149def output_def : Joined<["/", "-"], "output-def:">;156def output_def : Joined<["/", "-"], "output-def:">;
150def pdb_source_path : P<"pdbsourcepath",157def pdb_source_path : P<"pdbsourcepath",
151 "Base path used to make relative source file path absolute in PDB">;158 "Base path used to make relative source file path absolute in PDB">;
deps/lld/COFF/PDB.cpp+720-283
...@@ -16,12 +16,14 @@...@@ -16,12 +16,14 @@
16#include "Writer.h"16#include "Writer.h"
17#include "lld/Common/ErrorHandler.h"17#include "lld/Common/ErrorHandler.h"
18#include "lld/Common/Timer.h"18#include "lld/Common/Timer.h"
19#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
19#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"20#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
20#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"21#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
21#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"22#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
22#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"23#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
23#include "llvm/DebugInfo/CodeView/RecordName.h"24#include "llvm/DebugInfo/CodeView/RecordName.h"
24#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"25#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
26#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
25#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"27#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
26#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"28#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
27#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"29#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
...@@ -48,8 +50,10 @@...@@ -48,8 +50,10 @@
48#include "llvm/Object/CVDebugRecord.h"50#include "llvm/Object/CVDebugRecord.h"
49#include "llvm/Support/BinaryByteStream.h"51#include "llvm/Support/BinaryByteStream.h"
50#include "llvm/Support/Endian.h"52#include "llvm/Support/Endian.h"
53#include "llvm/Support/Errc.h"
51#include "llvm/Support/FormatVariadic.h"54#include "llvm/Support/FormatVariadic.h"
52#include "llvm/Support/JamCRC.h"55#include "llvm/Support/JamCRC.h"
56#include "llvm/Support/Parallel.h"
53#include "llvm/Support/Path.h"57#include "llvm/Support/Path.h"
54#include "llvm/Support/ScopedPrinter.h"58#include "llvm/Support/ScopedPrinter.h"
55#include <memory>59#include <memory>
...@@ -79,9 +83,14 @@ struct CVIndexMap {...@@ -79,9 +83,14 @@ struct CVIndexMap {
79 SmallVector<TypeIndex, 0> TPIMap;83 SmallVector<TypeIndex, 0> TPIMap;
80 SmallVector<TypeIndex, 0> IPIMap;84 SmallVector<TypeIndex, 0> IPIMap;
81 bool IsTypeServerMap = false;85 bool IsTypeServerMap = false;
86 bool IsPrecompiledTypeMap = false;
82};87};
8388
89class DebugSHandler;
90
84class PDBLinker {91class PDBLinker {
92 friend DebugSHandler;
93
85public:94public:
86 PDBLinker(SymbolTable *Symtab)95 PDBLinker(SymbolTable *Symtab)
87 : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),96 : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
...@@ -93,7 +102,7 @@ public:...@@ -93,7 +102,7 @@ public:
93 }102 }
94103
95 /// Emit the basic PDB structure: initial streams, headers, etc.104 /// Emit the basic PDB structure: initial streams, headers, etc.
96 void initialize(const llvm::codeview::DebugInfo &BuildId);105 void initialize(llvm::codeview::DebugInfo *BuildId);
97106
98 /// Add natvis files specified on the command line.107 /// Add natvis files specified on the command line.
99 void addNatvisFiles();108 void addNatvisFiles();
...@@ -101,8 +110,10 @@ public:...@@ -101,8 +110,10 @@ public:
101 /// Link CodeView from each object file in the symbol table into the PDB.110 /// Link CodeView from each object file in the symbol table into the PDB.
102 void addObjectsToPDB();111 void addObjectsToPDB();
103112
104 /// Link CodeView from a single object file into the PDB.113 /// Link CodeView from a single object file into the target (output) PDB.
105 void addObjFile(ObjFile *File);114 /// When a precompiled headers object is linked, its TPI map might be provided
115 /// externally.
116 void addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap = nullptr);
106117
107 /// Produce a mapping from the type and item indices used in the object118 /// Produce a mapping from the type and item indices used in the object
108 /// file to those in the destination PDB.119 /// file to those in the destination PDB.
...@@ -115,18 +126,60 @@ public:...@@ -115,18 +126,60 @@ public:
115 /// If the object does not use a type server PDB (compiled with /Z7), we merge126 /// If the object does not use a type server PDB (compiled with /Z7), we merge
116 /// all the type and item records from the .debug$S stream and fill in the127 /// all the type and item records from the .debug$S stream and fill in the
117 /// caller-provided ObjectIndexMap.128 /// caller-provided ObjectIndexMap.
118 Expected<const CVIndexMap&> mergeDebugT(ObjFile *File,129 Expected<const CVIndexMap &> mergeDebugT(ObjFile *File,
119 CVIndexMap &ObjectIndexMap);130 CVIndexMap *ObjectIndexMap);
131
132 /// Reads and makes available a PDB.
133 Expected<const CVIndexMap &> maybeMergeTypeServerPDB(ObjFile *File,
134 const CVType &FirstType);
135
136 /// Merges a precompiled headers TPI map into the current TPI map. The
137 /// precompiled headers object will also be loaded and remapped in the
138 /// process.
139 Expected<const CVIndexMap &>
140 mergeInPrecompHeaderObj(ObjFile *File, const CVType &FirstType,
141 CVIndexMap *ObjectIndexMap);
142
143 /// Reads and makes available a precompiled headers object.
144 ///
145 /// This is a requirement for objects compiled with cl.exe /Yu. In that
146 /// case, the referenced object (which was compiled with /Yc) has to be loaded
147 /// first. This is mainly because the current object's TPI stream has external
148 /// references to the precompiled headers object.
149 ///
150 /// If the precompiled headers object was already loaded, this function will
151 /// simply return its (remapped) TPI map.
152 Expected<const CVIndexMap &> aquirePrecompObj(ObjFile *File,
153 PrecompRecord Precomp);
154
155 /// Adds a precompiled headers object signature -> TPI mapping.
156 std::pair<CVIndexMap &, bool /*already there*/>
157 registerPrecompiledHeaders(uint32_t Signature);
120158
121 Expected<const CVIndexMap&> maybeMergeTypeServerPDB(ObjFile *File,159 void mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
122 TypeServer2Record &TS);160 std::vector<ulittle32_t *> &StringTableRefs,
161 BinaryStreamRef SymData);
123162
124 /// Add the section map and section contributions to the PDB.163 /// Add the section map and section contributions to the PDB.
125 void addSections(ArrayRef<OutputSection *> OutputSections,164 void addSections(ArrayRef<OutputSection *> OutputSections,
126 ArrayRef<uint8_t> SectionTable);165 ArrayRef<uint8_t> SectionTable);
127166
128 /// Write the PDB to disk.167 /// Get the type table or the global type table if /DEBUG:GHASH is enabled.
129 void commit();168 TypeCollection &getTypeTable() {
169 if (Config->DebugGHashes)
170 return GlobalTypeTable;
171 return TypeTable;
172 }
173
174 /// Get the ID table or the global ID table if /DEBUG:GHASH is enabled.
175 TypeCollection &getIDTable() {
176 if (Config->DebugGHashes)
177 return GlobalIDTable;
178 return IDTable;
179 }
180
181 /// Write the PDB to disk and store the Guid generated for it in *Guid.
182 void commit(codeview::GUID *Guid);
130183
131private:184private:
132 BumpPtrAllocator Alloc;185 BumpPtrAllocator Alloc;
...@@ -161,14 +214,101 @@ private:...@@ -161,14 +214,101 @@ private:
161 std::vector<pdb::SecMapEntry> SectionMap;214 std::vector<pdb::SecMapEntry> SectionMap;
162215
163 /// Type index mappings of type server PDBs that we've loaded so far.216 /// Type index mappings of type server PDBs that we've loaded so far.
164 std::map<GUID, CVIndexMap> TypeServerIndexMappings;217 std::map<codeview::GUID, CVIndexMap> TypeServerIndexMappings;
218
219 /// Type index mappings of precompiled objects type map that we've loaded so
220 /// far.
221 std::map<uint32_t, CVIndexMap> PrecompTypeIndexMappings;
165222
166 /// List of TypeServer PDBs which cannot be loaded.223 /// List of TypeServer PDBs which cannot be loaded.
167 /// Cached to prevent repeated load attempts.224 /// Cached to prevent repeated load attempts.
168 std::set<GUID> MissingTypeServerPDBs;225 std::map<codeview::GUID, std::string> MissingTypeServerPDBs;
226};
227
228class DebugSHandler {
229 PDBLinker &Linker;
230
231 /// The object file whose .debug$S sections we're processing.
232 ObjFile &File;
233
234 /// The result of merging type indices.
235 const CVIndexMap &IndexMap;
236
237 /// The DEBUG_S_STRINGTABLE subsection. These strings are referred to by
238 /// index from other records in the .debug$S section. All of these strings
239 /// need to be added to the global PDB string table, and all references to
240 /// these strings need to have their indices re-written to refer to the
241 /// global PDB string table.
242 DebugStringTableSubsectionRef CVStrTab;
243
244 /// The DEBUG_S_FILECHKSMS subsection. As above, these are referred to
245 /// by other records in the .debug$S section and need to be merged into the
246 /// PDB.
247 DebugChecksumsSubsectionRef Checksums;
248
249 /// The DEBUG_S_FRAMEDATA subsection(s). There can be more than one of
250 /// these and they need not appear in any specific order. However, they
251 /// contain string table references which need to be re-written, so we
252 /// collect them all here and re-write them after all subsections have been
253 /// discovered and processed.
254 std::vector<DebugFrameDataSubsectionRef> NewFpoFrames;
255
256 /// Pointers to raw memory that we determine have string table references
257 /// that need to be re-written. We first process all .debug$S subsections
258 /// to ensure that we can handle subsections written in any order, building
259 /// up this list as we go. At the end, we use the string table (which must
260 /// have been discovered by now else it is an error) to re-write these
261 /// references.
262 std::vector<ulittle32_t *> StringTableReferences;
263
264public:
265 DebugSHandler(PDBLinker &Linker, ObjFile &File, const CVIndexMap &IndexMap)
266 : Linker(Linker), File(File), IndexMap(IndexMap) {}
267
268 void handleDebugS(lld::coff::SectionChunk &DebugS);
269 void finish();
169};270};
170}271}
171272
273// Visual Studio's debugger requires absolute paths in various places in the
274// PDB to work without additional configuration:
275// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box
276static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
277 // The default behavior is to produce paths that are valid within the context
278 // of the machine that you perform the link on. If the linker is running on
279 // a POSIX system, we will output absolute POSIX paths. If the linker is
280 // running on a Windows system, we will output absolute Windows paths. If the
281 // user desires any other kind of behavior, they should explicitly pass
282 // /pdbsourcepath, in which case we will treat the exact string the user
283 // passed in as the gospel and not normalize, canonicalize it.
284 if (sys::path::is_absolute(FileName, sys::path::Style::windows) ||
285 sys::path::is_absolute(FileName, sys::path::Style::posix))
286 return;
287
288 // It's not absolute in any path syntax. Relative paths necessarily refer to
289 // the local file system, so we can make it native without ending up with a
290 // nonsensical path.
291 if (Config->PDBSourcePath.empty()) {
292 sys::path::native(FileName);
293 sys::fs::make_absolute(FileName);
294 return;
295 }
296
297 // Try to guess whether /PDBSOURCEPATH is a unix path or a windows path.
298 // Since PDB's are more of a Windows thing, we make this conservative and only
299 // decide that it's a unix path if we're fairly certain. Specifically, if
300 // it starts with a forward slash.
301 SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
302 sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/")
303 ? sys::path::Style::posix
304 : sys::path::Style::windows;
305 sys::path::append(AbsoluteFileName, GuessedStyle, FileName);
306 sys::path::native(AbsoluteFileName, GuessedStyle);
307 sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle);
308
309 FileName = std::move(AbsoluteFileName);
310}
311
172static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,312static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,
173 StringRef Name) {313 StringRef Name) {
174 for (SectionChunk *C : Sections)314 for (SectionChunk *C : Sections)
...@@ -242,27 +382,79 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,...@@ -242,27 +382,79 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
242 });382 });
243}383}
244384
245static Optional<TypeServer2Record>385// OBJs usually start their symbol stream with a S_OBJNAME record. This record
246maybeReadTypeServerRecord(CVTypeArray &Types) {386// also contains the signature/key of the current PCH session. The signature
247 auto I = Types.begin();387// must be same for all objects which depend on the precompiled object.
248 if (I == Types.end())388// Recompiling the precompiled headers will generate a new PCH key and thus
249 return None;389// invalidate all the dependent objects.
250 const CVType &Type = *I;390static uint32_t extractPCHSignature(ObjFile *File) {
251 if (Type.kind() != LF_TYPESERVER2)391 auto DbgIt = find_if(File->getDebugChunks(), [](SectionChunk *C) {
252 return None;392 return C->getSectionName() == ".debug$S";
253 TypeServer2Record TS;393 });
254 if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))394 if (!DbgIt)
255 fatal("error reading type server record: " + toString(std::move(EC)));395 return 0;
256 return std::move(TS);396
397 ArrayRef<uint8_t> Contents =
398 consumeDebugMagic((*DbgIt)->getContents(), ".debug$S");
399 DebugSubsectionArray Subsections;
400 BinaryStreamReader Reader(Contents, support::little);
401 ExitOnErr(Reader.readArray(Subsections, Contents.size()));
402
403 for (const DebugSubsectionRecord &SS : Subsections) {
404 if (SS.kind() != DebugSubsectionKind::Symbols)
405 continue;
406
407 // If it's there, the S_OBJNAME record shall come first in the stream.
408 Expected<CVSymbol> Sym = readSymbolFromStream(SS.getRecordData(), 0);
409 if (!Sym) {
410 consumeError(Sym.takeError());
411 continue;
412 }
413 if (auto ObjName = SymbolDeserializer::deserializeAs<ObjNameSym>(Sym.get()))
414 return ObjName->Signature;
415 }
416 return 0;
257}417}
258418
259Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,419Expected<const CVIndexMap &>
260 CVIndexMap &ObjectIndexMap) {420PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) {
261 ScopedTimer T(TypeMergingTimer);421 ScopedTimer T(TypeMergingTimer);
262422
423 bool IsPrecompiledHeader = false;
424
263 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");425 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
426 if (Data.empty()) {
427 // Try again, Microsoft precompiled headers use .debug$P instead of
428 // .debug$T
429 Data = getDebugSection(File, ".debug$P");
430 IsPrecompiledHeader = true;
431 }
264 if (Data.empty())432 if (Data.empty())
265 return ObjectIndexMap;433 return *ObjectIndexMap; // no debug info
434
435 // Precompiled headers objects need to save the index map for further
436 // reference by other objects which use the precompiled headers.
437 if (IsPrecompiledHeader) {
438 uint32_t PCHSignature = extractPCHSignature(File);
439 if (PCHSignature == 0)
440 fatal("No signature found for the precompiled headers OBJ (" +
441 File->getName() + ")");
442
443 // When a precompiled headers object comes first on the command-line, we
444 // update the mapping here. Otherwise, if an object referencing the
445 // precompiled headers object comes first, the mapping is created in
446 // aquirePrecompObj(), thus we would skip this block.
447 if (!ObjectIndexMap->IsPrecompiledTypeMap) {
448 auto R = registerPrecompiledHeaders(PCHSignature);
449 if (R.second)
450 fatal(
451 "A precompiled headers OBJ with the same signature was already "
452 "provided! (" +
453 File->getName() + ")");
454
455 ObjectIndexMap = &R.first;
456 }
457 }
266458
267 BinaryByteStream Stream(Data, support::little);459 BinaryByteStream Stream(Data, support::little);
268 CVTypeArray Types;460 CVTypeArray Types;
...@@ -270,13 +462,32 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,...@@ -270,13 +462,32 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
270 if (auto EC = Reader.readArray(Types, Reader.getLength()))462 if (auto EC = Reader.readArray(Types, Reader.getLength()))
271 fatal("Reader::readArray failed: " + toString(std::move(EC)));463 fatal("Reader::readArray failed: " + toString(std::move(EC)));
272464
273 // Look through type servers. If we've already seen this type server, don't465 auto FirstType = Types.begin();
274 // merge any type information.466 if (FirstType == Types.end())
275 if (Optional<TypeServer2Record> TS = maybeReadTypeServerRecord(Types))467 return *ObjectIndexMap;
276 return maybeMergeTypeServerPDB(File, *TS);468
469 if (FirstType->kind() == LF_TYPESERVER2) {
470 // Look through type servers. If we've already seen this type server,
471 // don't merge any type information.
472 return maybeMergeTypeServerPDB(File, *FirstType);
473 } else if (FirstType->kind() == LF_PRECOMP) {
474 // This object was compiled with /Yu, so process the corresponding
475 // precompiled headers object (/Yc) first. Some type indices in the current
476 // object are referencing data in the precompiled headers object, so we need
477 // both to be loaded.
478 auto E = mergeInPrecompHeaderObj(File, *FirstType, ObjectIndexMap);
479 if (!E)
480 return E.takeError();
481
482 // Drop LF_PRECOMP record from the input stream, as it needs to be replaced
483 // with the precompiled headers object type stream.
484 // Note that we can't just call Types.drop_front(), as we explicitly want to
485 // rebase the stream.
486 Types.setUnderlyingStream(
487 Types.getUnderlyingStream().drop_front(FirstType->RecordData.size()));
488 }
277489
278 // This is a /Z7 object. Fill in the temporary, caller-provided490 // Fill in the temporary, caller-provided ObjectIndexMap.
279 // ObjectIndexMap.
280 if (Config->DebugGHashes) {491 if (Config->DebugGHashes) {
281 ArrayRef<GloballyHashedType> Hashes;492 ArrayRef<GloballyHashedType> Hashes;
282 std::vector<GloballyHashedType> OwnedHashes;493 std::vector<GloballyHashedType> OwnedHashes;
...@@ -288,20 +499,28 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,...@@ -288,20 +499,28 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
288 }499 }
289500
290 if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,501 if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
291 ObjectIndexMap.TPIMap, Types, Hashes))502 ObjectIndexMap->TPIMap, Types, Hashes,
503 File->PCHSignature))
292 fatal("codeview::mergeTypeAndIdRecords failed: " +504 fatal("codeview::mergeTypeAndIdRecords failed: " +
293 toString(std::move(Err)));505 toString(std::move(Err)));
294 } else {506 } else {
295 if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,507 if (auto Err =
296 ObjectIndexMap.TPIMap, Types))508 mergeTypeAndIdRecords(IDTable, TypeTable, ObjectIndexMap->TPIMap,
509 Types, File->PCHSignature))
297 fatal("codeview::mergeTypeAndIdRecords failed: " +510 fatal("codeview::mergeTypeAndIdRecords failed: " +
298 toString(std::move(Err)));511 toString(std::move(Err)));
299 }512 }
300 return ObjectIndexMap;513 return *ObjectIndexMap;
301}514}
302515
303static Expected<std::unique_ptr<pdb::NativeSession>>516static Expected<std::unique_ptr<pdb::NativeSession>>
304tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {517tryToLoadPDB(const codeview::GUID &GuidFromObj, StringRef TSPath) {
518 // Ensure the file exists before anything else. We want to return ENOENT,
519 // "file not found", even if the path points to a removable device (in which
520 // case the return message would be EAGAIN, "resource unavailable try again")
521 if (!llvm::sys::fs::exists(TSPath))
522 return errorCodeToError(std::error_code(ENOENT, std::generic_category()));
523
305 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(524 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(
306 TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);525 TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
307 if (!MBOrErr)526 if (!MBOrErr)
...@@ -326,21 +545,27 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {...@@ -326,21 +545,27 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
326 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID545 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
327 // must match the GUID specified in the TypeServer2 record.546 // must match the GUID specified in the TypeServer2 record.
328 if (ExpectedInfo->getGuid() != GuidFromObj)547 if (ExpectedInfo->getGuid() != GuidFromObj)
329 return make_error<pdb::GenericError>(548 return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
330 pdb::generic_error_code::type_server_not_found, TSPath);
331549
332 return std::move(NS);550 return std::move(NS);
333}551}
334552
335Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,553Expected<const CVIndexMap &>
336 TypeServer2Record &TS) {554PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, const CVType &FirstType) {
337 const GUID& TSId = TS.getGuid();555 TypeServer2Record TS;
556 if (auto EC =
557 TypeDeserializer::deserializeAs(const_cast<CVType &>(FirstType), TS))
558 fatal("error reading record: " + toString(std::move(EC)));
559
560 const codeview::GUID &TSId = TS.getGuid();
338 StringRef TSPath = TS.getName();561 StringRef TSPath = TS.getName();
339562
340 // First, check if the PDB has previously failed to load.563 // First, check if the PDB has previously failed to load.
341 if (MissingTypeServerPDBs.count(TSId))564 auto PrevErr = MissingTypeServerPDBs.find(TSId);
342 return make_error<pdb::GenericError>(565 if (PrevErr != MissingTypeServerPDBs.end())
343 pdb::generic_error_code::type_server_not_found, TSPath);566 return createFileError(
567 TSPath,
568 make_error<StringError>(PrevErr->second, inconvertibleErrorCode()));
344569
345 // Second, check if we already loaded a PDB with this GUID. Return the type570 // Second, check if we already loaded a PDB with this GUID. Return the type
346 // index mapping if we have it.571 // index mapping if we have it.
...@@ -355,20 +580,39 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,...@@ -355,20 +580,39 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
355 // Check for a PDB at:580 // Check for a PDB at:
356 // 1. The given file path581 // 1. The given file path
357 // 2. Next to the object file or archive file582 // 2. Next to the object file or archive file
358 auto ExpectedSession = tryToLoadPDB(TSId, TSPath);583 auto ExpectedSession = handleExpected(
359 if (!ExpectedSession) {584 tryToLoadPDB(TSId, TSPath),
360 consumeError(ExpectedSession.takeError());585 [&]() {
361 StringRef LocalPath =586 StringRef LocalPath =
362 !File->ParentName.empty() ? File->ParentName : File->getName();587 !File->ParentName.empty() ? File->ParentName : File->getName();
363 SmallString<128> Path = sys::path::parent_path(LocalPath);588 SmallString<128> Path = sys::path::parent_path(LocalPath);
364 sys::path::append(589 // Currently, type server PDBs are only created by cl, which only runs
365 Path, sys::path::filename(TSPath, sys::path::Style::windows));590 // on Windows, so we can assume type server paths are Windows style.
366 ExpectedSession = tryToLoadPDB(TSId, Path);591 sys::path::append(
367 }592 Path, sys::path::filename(TSPath, sys::path::Style::windows));
593 return tryToLoadPDB(TSId, Path);
594 },
595 [&](std::unique_ptr<ECError> EC) -> Error {
596 auto SysErr = EC->convertToErrorCode();
597 // Only re-try loading if the previous error was "No such file or
598 // directory"
599 if (SysErr.category() == std::generic_category() &&
600 SysErr.value() == ENOENT)
601 return Error::success();
602 return Error(std::move(EC));
603 });
604
368 if (auto E = ExpectedSession.takeError()) {605 if (auto E = ExpectedSession.takeError()) {
369 TypeServerIndexMappings.erase(TSId);606 TypeServerIndexMappings.erase(TSId);
370 MissingTypeServerPDBs.emplace(TSId);607
371 return std::move(E);608 // Flatten the error to a string, for later display, if the error occurs
609 // again on the same PDB.
610 std::string ErrMsg;
611 raw_string_ostream S(ErrMsg);
612 S << E;
613 MissingTypeServerPDBs.emplace(TSId, S.str());
614
615 return createFileError(TSPath, std::move(E));
372 }616 }
373617
374 pdb::NativeSession *Session = ExpectedSession->get();618 pdb::NativeSession *Session = ExpectedSession->get();
...@@ -394,9 +638,10 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,...@@ -394,9 +638,10 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
394 auto IpiHashes =638 auto IpiHashes =
395 GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);639 GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
396640
641 Optional<uint32_t> EndPrecomp;
397 // Merge TPI first, because the IPI stream will reference type indices.642 // Merge TPI first, because the IPI stream will reference type indices.
398 if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,643 if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
399 ExpectedTpi->typeArray(), TpiHashes))644 ExpectedTpi->typeArray(), TpiHashes, EndPrecomp))
400 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));645 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
401646
402 // Merge IPI.647 // Merge IPI.
...@@ -419,6 +664,103 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,...@@ -419,6 +664,103 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
419 return IndexMap;664 return IndexMap;
420}665}
421666
667Expected<const CVIndexMap &>
668PDBLinker::mergeInPrecompHeaderObj(ObjFile *File, const CVType &FirstType,
669 CVIndexMap *ObjectIndexMap) {
670 PrecompRecord Precomp;
671 if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(FirstType),
672 Precomp))
673 fatal("error reading record: " + toString(std::move(EC)));
674
675 auto E = aquirePrecompObj(File, Precomp);
676 if (!E)
677 return E.takeError();
678
679 const CVIndexMap &PrecompIndexMap = *E;
680 assert(PrecompIndexMap.IsPrecompiledTypeMap);
681
682 if (PrecompIndexMap.TPIMap.empty())
683 return PrecompIndexMap;
684
685 assert(Precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex);
686 assert(Precomp.getTypesCount() <= PrecompIndexMap.TPIMap.size());
687 // Use the previously remapped index map from the precompiled headers.
688 ObjectIndexMap->TPIMap.append(PrecompIndexMap.TPIMap.begin(),
689 PrecompIndexMap.TPIMap.begin() +
690 Precomp.getTypesCount());
691 return *ObjectIndexMap;
692}
693
694static bool equals_path(StringRef path1, StringRef path2) {
695#if defined(_WIN32)
696 return path1.equals_lower(path2);
697#else
698 return path1.equals(path2);
699#endif
700}
701
702// Find by name an OBJ provided on the command line
703static ObjFile *findObjByName(StringRef FileNameOnly) {
704 SmallString<128> CurrentPath;
705
706 for (ObjFile *F : ObjFile::Instances) {
707 StringRef CurrentFileName = sys::path::filename(F->getName());
708
709 // Compare based solely on the file name (link.exe behavior)
710 if (equals_path(CurrentFileName, FileNameOnly))
711 return F;
712 }
713 return nullptr;
714}
715
716std::pair<CVIndexMap &, bool /*already there*/>
717PDBLinker::registerPrecompiledHeaders(uint32_t Signature) {
718 auto Insertion = PrecompTypeIndexMappings.insert({Signature, CVIndexMap()});
719 CVIndexMap &IndexMap = Insertion.first->second;
720 if (!Insertion.second)
721 return {IndexMap, true};
722 // Mark this map as a precompiled types map.
723 IndexMap.IsPrecompiledTypeMap = true;
724 return {IndexMap, false};
725}
726
727Expected<const CVIndexMap &>
728PDBLinker::aquirePrecompObj(ObjFile *File, PrecompRecord Precomp) {
729 // First, check if we already loaded the precompiled headers object with this
730 // signature. Return the type index mapping if we've already seen it.
731 auto R = registerPrecompiledHeaders(Precomp.getSignature());
732 if (R.second)
733 return R.first;
734
735 CVIndexMap &IndexMap = R.first;
736
737 // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
738 // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
739 // the paths embedded in the OBJs are in the Windows format.
740 SmallString<128> PrecompFileName = sys::path::filename(
741 Precomp.getPrecompFilePath(), sys::path::Style::windows);
742
743 // link.exe requires that a precompiled headers object must always be provided
744 // on the command-line, even if that's not necessary.
745 auto PrecompFile = findObjByName(PrecompFileName);
746 if (!PrecompFile)
747 return createFileError(
748 PrecompFileName.str(),
749 make_error<pdb::PDBError>(pdb::pdb_error_code::external_cmdline_ref));
750
751 addObjFile(PrecompFile, &IndexMap);
752
753 if (!PrecompFile->PCHSignature)
754 fatal(PrecompFile->getName() + " is not a precompiled headers object");
755
756 if (Precomp.getSignature() != PrecompFile->PCHSignature.getValueOr(0))
757 return createFileError(
758 Precomp.getPrecompFilePath().str(),
759 make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
760
761 return IndexMap;
762}
763
422static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {764static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
423 if (TI.isSimple())765 if (TI.isSimple())
424 return true;766 return true;
...@@ -429,9 +771,11 @@ static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {...@@ -429,9 +771,11 @@ static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
429}771}
430772
431static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind,773static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind,
432 MutableArrayRef<uint8_t> Contents,774 MutableArrayRef<uint8_t> RecordBytes,
433 const CVIndexMap &IndexMap,775 const CVIndexMap &IndexMap,
434 ArrayRef<TiReference> TypeRefs) {776 ArrayRef<TiReference> TypeRefs) {
777 MutableArrayRef<uint8_t> Contents =
778 RecordBytes.drop_front(sizeof(RecordPrefix));
435 for (const TiReference &Ref : TypeRefs) {779 for (const TiReference &Ref : TypeRefs) {
436 unsigned ByteSize = Ref.Count * sizeof(TypeIndex);780 unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
437 if (Contents.size() < Ref.Offset + ByteSize)781 if (Contents.size() < Ref.Offset + ByteSize)
...@@ -477,7 +821,7 @@ recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents,...@@ -477,7 +821,7 @@ recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents,
477 switch (Kind) {821 switch (Kind) {
478 case SymbolKind::S_FILESTATIC:822 case SymbolKind::S_FILESTATIC:
479 // FileStaticSym::ModFileOffset823 // FileStaticSym::ModFileOffset
480 recordStringTableReferenceAtOffset(Contents, 4, StrTableRefs);824 recordStringTableReferenceAtOffset(Contents, 8, StrTableRefs);
481 break;825 break;
482 case SymbolKind::S_DEFRANGE:826 case SymbolKind::S_DEFRANGE:
483 case SymbolKind::S_DEFRANGE_SUBFIELD:827 case SymbolKind::S_DEFRANGE_SUBFIELD:
...@@ -542,58 +886,26 @@ static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData,...@@ -542,58 +886,26 @@ static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData,
542886
543/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.887/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
544/// The object file may not be aligned.888/// The object file may not be aligned.
545static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym,889static MutableArrayRef<uint8_t>
546 BumpPtrAllocator &Alloc) {890copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef<uint8_t> &AlignedMem) {
547 size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));891 size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
548 assert(Size >= 4 && "record too short");892 assert(Size >= 4 && "record too short");
549 assert(Size <= MaxRecordLength && "record too long");893 assert(Size <= MaxRecordLength && "record too long");
550 void *Mem = Alloc.Allocate(Size, 4);894 assert(AlignedMem.size() >= Size && "didn't preallocate enough");
551895
552 // Copy the symbol record and zero out any padding bytes.896 // Copy the symbol record and zero out any padding bytes.
553 MutableArrayRef<uint8_t> NewData(reinterpret_cast<uint8_t *>(Mem), Size);897 MutableArrayRef<uint8_t> NewData = AlignedMem.take_front(Size);
898 AlignedMem = AlignedMem.drop_front(Size);
554 memcpy(NewData.data(), Sym.data().data(), Sym.length());899 memcpy(NewData.data(), Sym.data().data(), Sym.length());
555 memset(NewData.data() + Sym.length(), 0, Size - Sym.length());900 memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
556901
557 // Update the record prefix length. It should point to the beginning of the902 // Update the record prefix length. It should point to the beginning of the
558 // next record.903 // next record.
559 auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem);904 auto *Prefix = reinterpret_cast<RecordPrefix *>(NewData.data());
560 Prefix->RecordLen = Size - 2;905 Prefix->RecordLen = Size - 2;
561 return NewData;906 return NewData;
562}907}
563908
564/// Return true if this symbol opens a scope. This implies that the symbol has
565/// "parent" and "end" fields, which contain the offset of the S_END or
566/// S_INLINESITE_END record.
567static bool symbolOpensScope(SymbolKind Kind) {
568 switch (Kind) {
569 case SymbolKind::S_GPROC32:
570 case SymbolKind::S_LPROC32:
571 case SymbolKind::S_LPROC32_ID:
572 case SymbolKind::S_GPROC32_ID:
573 case SymbolKind::S_BLOCK32:
574 case SymbolKind::S_SEPCODE:
575 case SymbolKind::S_THUNK32:
576 case SymbolKind::S_INLINESITE:
577 case SymbolKind::S_INLINESITE2:
578 return true;
579 default:
580 break;
581 }
582 return false;
583}
584
585static bool symbolEndsScope(SymbolKind Kind) {
586 switch (Kind) {
587 case SymbolKind::S_END:
588 case SymbolKind::S_PROC_ID_END:
589 case SymbolKind::S_INLINESITE_END:
590 return true;
591 default:
592 break;
593 }
594 return false;
595}
596
597struct ScopeRecord {909struct ScopeRecord {
598 ulittle32_t PtrParent;910 ulittle32_t PtrParent;
599 ulittle32_t PtrEnd;911 ulittle32_t PtrEnd;
...@@ -625,11 +937,10 @@ static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,...@@ -625,11 +937,10 @@ static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
625 S.OpeningRecord->PtrEnd = CurOffset;937 S.OpeningRecord->PtrEnd = CurOffset;
626}938}
627939
628static bool symbolGoesInModuleStream(const CVSymbol &Sym) {940static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) {
629 switch (Sym.kind()) {941 switch (Sym.kind()) {
630 case SymbolKind::S_GDATA32:942 case SymbolKind::S_GDATA32:
631 case SymbolKind::S_CONSTANT:943 case SymbolKind::S_CONSTANT:
632 case SymbolKind::S_UDT:
633 // We really should not be seeing S_PROCREF and S_LPROCREF in the first place944 // We really should not be seeing S_PROCREF and S_LPROCREF in the first place
634 // since they are synthesized by the linker in response to S_GPROC32 and945 // since they are synthesized by the linker in response to S_GPROC32 and
635 // S_LPROC32, but if we do see them, don't put them in the module stream I946 // S_LPROC32, but if we do see them, don't put them in the module stream I
...@@ -637,6 +948,9 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym) {...@@ -637,6 +948,9 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym) {
637 case SymbolKind::S_PROCREF:948 case SymbolKind::S_PROCREF:
638 case SymbolKind::S_LPROCREF:949 case SymbolKind::S_LPROCREF:
639 return false;950 return false;
951 // S_UDT records go in the module stream if it is not a global S_UDT.
952 case SymbolKind::S_UDT:
953 return !IsGlobalScope;
640 // S_GDATA32 does not go in the module stream, but S_LDATA32 does.954 // S_GDATA32 does not go in the module stream, but S_LDATA32 does.
641 case SymbolKind::S_LDATA32:955 case SymbolKind::S_LDATA32:
642 default:956 default:
...@@ -644,7 +958,7 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym) {...@@ -644,7 +958,7 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym) {
644 }958 }
645}959}
646960
647static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) {961static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) {
648 switch (Sym.kind()) {962 switch (Sym.kind()) {
649 case SymbolKind::S_CONSTANT:963 case SymbolKind::S_CONSTANT:
650 case SymbolKind::S_GDATA32:964 case SymbolKind::S_GDATA32:
...@@ -658,20 +972,16 @@ static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) {...@@ -658,20 +972,16 @@ static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) {
658 case SymbolKind::S_PROCREF:972 case SymbolKind::S_PROCREF:
659 case SymbolKind::S_LPROCREF:973 case SymbolKind::S_LPROCREF:
660 return true;974 return true;
661 // FIXME: For now, we drop all S_UDT symbols (i.e. they don't go in the975 // S_UDT records go in the globals stream if it is a global S_UDT.
662 // globals stream or the modules stream). These have special handling which
663 // needs more investigation before we can get right, but by putting them all
664 // into the globals stream WinDbg fails to display local variables of class
665 // types saying that it cannot find the type Foo *. So as a stopgap just to
666 // keep things working, we drop them.
667 case SymbolKind::S_UDT:976 case SymbolKind::S_UDT:
977 return IsGlobalScope;
668 default:978 default:
669 return false;979 return false;
670 }980 }
671}981}
672982
673static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,983static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex,
674 const CVSymbol &Sym) {984 unsigned SymOffset, const CVSymbol &Sym) {
675 switch (Sym.kind()) {985 switch (Sym.kind()) {
676 case SymbolKind::S_CONSTANT:986 case SymbolKind::S_CONSTANT:
677 case SymbolKind::S_UDT:987 case SymbolKind::S_UDT:
...@@ -687,12 +997,12 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,...@@ -687,12 +997,12 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,
687 if (Sym.kind() == SymbolKind::S_LPROC32)997 if (Sym.kind() == SymbolKind::S_LPROC32)
688 K = SymbolRecordKind::LocalProcRef;998 K = SymbolRecordKind::LocalProcRef;
689 ProcRefSym PS(K);999 ProcRefSym PS(K);
690 PS.Module = static_cast<uint16_t>(File.ModuleDBI->getModuleIndex());1000 PS.Module = ModIndex;
691 // For some reason, MSVC seems to add one to this value.1001 // For some reason, MSVC seems to add one to this value.
692 ++PS.Module;1002 ++PS.Module;
693 PS.Name = getSymbolName(Sym);1003 PS.Name = getSymbolName(Sym);
694 PS.SumName = 0;1004 PS.SumName = 0;
695 PS.SymOffset = File.ModuleDBI->getNextSymbolOffset();1005 PS.SymOffset = SymOffset;
696 Builder.addGlobalSymbol(PS);1006 Builder.addGlobalSymbol(PS);
697 break;1007 break;
698 }1008 }
...@@ -701,20 +1011,62 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,...@@ -701,20 +1011,62 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,
701 }1011 }
702}1012}
7031013
704static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File,1014void PDBLinker::mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
705 pdb::GSIStreamBuilder &GsiBuilder,1015 std::vector<ulittle32_t *> &StringTableRefs,
706 const CVIndexMap &IndexMap,1016 BinaryStreamRef SymData) {
707 TypeCollection &IDTable,
708 std::vector<ulittle32_t *> &StringTableRefs,
709 BinaryStreamRef SymData) {
710 // FIXME: Improve error recovery by warning and skipping records when
711 // possible.
712 ArrayRef<uint8_t> SymsBuffer;1017 ArrayRef<uint8_t> SymsBuffer;
713 cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer));1018 cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer));
714 SmallVector<SymbolScope, 4> Scopes;1019 SmallVector<SymbolScope, 4> Scopes;
7151020
1021 // Iterate every symbol to check if any need to be realigned, and if so, how
1022 // much space we need to allocate for them.
1023 bool NeedsRealignment = false;
1024 unsigned TotalRealignedSize = 0;
716 auto EC = forEachCodeViewRecord<CVSymbol>(1025 auto EC = forEachCodeViewRecord<CVSymbol>(
717 SymsBuffer, [&](const CVSymbol &Sym) -> llvm::Error {1026 SymsBuffer, [&](CVSymbol Sym) -> llvm::Error {
1027 unsigned RealignedSize =
1028 alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
1029 NeedsRealignment |= RealignedSize != Sym.length();
1030 TotalRealignedSize += RealignedSize;
1031 return Error::success();
1032 });
1033
1034 // If any of the symbol record lengths was corrupt, ignore them all, warn
1035 // about it, and move on.
1036 if (EC) {
1037 warn("corrupt symbol records in " + File->getName());
1038 consumeError(std::move(EC));
1039 return;
1040 }
1041
1042 // If any symbol needed realignment, allocate enough contiguous memory for
1043 // them all. Typically symbol subsections are small enough that this will not
1044 // cause fragmentation.
1045 MutableArrayRef<uint8_t> AlignedSymbolMem;
1046 if (NeedsRealignment) {
1047 void *AlignedData =
1048 Alloc.Allocate(TotalRealignedSize, alignOf(CodeViewContainer::Pdb));
1049 AlignedSymbolMem = makeMutableArrayRef(
1050 reinterpret_cast<uint8_t *>(AlignedData), TotalRealignedSize);
1051 }
1052
1053 // Iterate again, this time doing the real work.
1054 unsigned CurSymOffset = File->ModuleDBI->getNextSymbolOffset();
1055 ArrayRef<uint8_t> BulkSymbols;
1056 cantFail(forEachCodeViewRecord<CVSymbol>(
1057 SymsBuffer, [&](CVSymbol Sym) -> llvm::Error {
1058 // Align the record if required.
1059 MutableArrayRef<uint8_t> RecordBytes;
1060 if (NeedsRealignment) {
1061 RecordBytes = copyAndAlignSymbol(Sym, AlignedSymbolMem);
1062 Sym = CVSymbol(Sym.kind(), RecordBytes);
1063 } else {
1064 // Otherwise, we can actually mutate the symbol directly, since we
1065 // copied it to apply relocations.
1066 RecordBytes = makeMutableArrayRef(
1067 const_cast<uint8_t *>(Sym.data().data()), Sym.length());
1068 }
1069
718 // Discover type index references in the record. Skip it if we don't1070 // Discover type index references in the record. Skip it if we don't
719 // know where they are.1071 // know where they are.
720 SmallVector<TiReference, 32> TypeRefs;1072 SmallVector<TiReference, 32> TypeRefs;
...@@ -724,57 +1076,62 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File,...@@ -724,57 +1076,62 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File,
724 return Error::success();1076 return Error::success();
725 }1077 }
7261078
727 // Copy the symbol record so we can mutate it.
728 MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc);
729
730 // Re-map all the type index references.1079 // Re-map all the type index references.
731 MutableArrayRef<uint8_t> Contents =1080 remapTypesInSymbolRecord(File, Sym.kind(), RecordBytes, IndexMap,
732 NewData.drop_front(sizeof(RecordPrefix));
733 remapTypesInSymbolRecord(File, Sym.kind(), Contents, IndexMap,
734 TypeRefs);1081 TypeRefs);
7351082
736 // An object file may have S_xxx_ID symbols, but these get converted to1083 // An object file may have S_xxx_ID symbols, but these get converted to
737 // "real" symbols in a PDB.1084 // "real" symbols in a PDB.
738 translateIdSymbols(NewData, IDTable);1085 translateIdSymbols(RecordBytes, getIDTable());
1086 Sym = CVSymbol(symbolKind(RecordBytes), RecordBytes);
7391087
740 // If this record refers to an offset in the object file's string table,1088 // If this record refers to an offset in the object file's string table,
741 // add that item to the global PDB string table and re-write the index.1089 // add that item to the global PDB string table and re-write the index.
742 recordStringTableReferences(Sym.kind(), Contents, StringTableRefs);1090 recordStringTableReferences(Sym.kind(), RecordBytes, StringTableRefs);
743
744 SymbolKind NewKind = symbolKind(NewData);
7451091
746 // Fill in "Parent" and "End" fields by maintaining a stack of scopes.1092 // Fill in "Parent" and "End" fields by maintaining a stack of scopes.
747 CVSymbol NewSym(NewKind, NewData);1093 if (symbolOpensScope(Sym.kind()))
748 if (symbolOpensScope(NewKind))1094 scopeStackOpen(Scopes, CurSymOffset, Sym);
749 scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(),1095 else if (symbolEndsScope(Sym.kind()))
750 NewSym);1096 scopeStackClose(Scopes, CurSymOffset, File);
751 else if (symbolEndsScope(NewKind))
752 scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File);
7531097
754 // Add the symbol to the globals stream if necessary. Do this before1098 // Add the symbol to the globals stream if necessary. Do this before
755 // adding the symbol to the module since we may need to get the next1099 // adding the symbol to the module since we may need to get the next
756 // symbol offset, and writing to the module's symbol stream will update1100 // symbol offset, and writing to the module's symbol stream will update
757 // that offset.1101 // that offset.
758 if (symbolGoesInGlobalsStream(NewSym))1102 if (symbolGoesInGlobalsStream(Sym, Scopes.empty()))
759 addGlobalSymbol(GsiBuilder, *File, NewSym);1103 addGlobalSymbol(Builder.getGsiBuilder(),
7601104 File->ModuleDBI->getModuleIndex(), CurSymOffset, Sym);
761 // Add the symbol to the module.1105
762 if (symbolGoesInModuleStream(NewSym))1106 if (symbolGoesInModuleStream(Sym, Scopes.empty())) {
763 File->ModuleDBI->addSymbol(NewSym);1107 // Add symbols to the module in bulk. If this symbol is contiguous
1108 // with the previous run of symbols to add, combine the ranges. If
1109 // not, close the previous range of symbols and start a new one.
1110 if (Sym.data().data() == BulkSymbols.end()) {
1111 BulkSymbols = makeArrayRef(BulkSymbols.data(),
1112 BulkSymbols.size() + Sym.length());
1113 } else {
1114 File->ModuleDBI->addSymbolsInBulk(BulkSymbols);
1115 BulkSymbols = RecordBytes;
1116 }
1117 CurSymOffset += Sym.length();
1118 }
764 return Error::success();1119 return Error::success();
765 });1120 }));
766 cantFail(std::move(EC));1121
1122 // Add any remaining symbols we've accumulated.
1123 File->ModuleDBI->addSymbolsInBulk(BulkSymbols);
767}1124}
7681125
769// Allocate memory for a .debug$S section and relocate it.1126// Allocate memory for a .debug$S / .debug$F section and relocate it.
770static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,1127static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
771 SectionChunk *DebugChunk) {1128 SectionChunk &DebugChunk) {
772 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());1129 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
773 assert(DebugChunk->OutputSectionOff == 0 &&1130 assert(DebugChunk.OutputSectionOff == 0 &&
774 "debug sections should not be in output sections");1131 "debug sections should not be in output sections");
775 DebugChunk->writeTo(Buffer);1132 DebugChunk.readRelocTargets();
776 return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),1133 DebugChunk.writeTo(Buffer);
777 ".debug$S");1134 return makeArrayRef(Buffer, DebugChunk.getSize());
778}1135}
7791136
780static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {1137static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
...@@ -803,25 +1160,137 @@ static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {...@@ -803,25 +1160,137 @@ static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
803 return SC;1160 return SC;
804}1161}
8051162
806void PDBLinker::addObjFile(ObjFile *File) {1163static uint32_t
1164translateStringTableIndex(uint32_t ObjIndex,
1165 const DebugStringTableSubsectionRef &ObjStrTable,
1166 DebugStringTableSubsection &PdbStrTable) {
1167 auto ExpectedString = ObjStrTable.getString(ObjIndex);
1168 if (!ExpectedString) {
1169 warn("Invalid string table reference");
1170 consumeError(ExpectedString.takeError());
1171 return 0;
1172 }
1173
1174 return PdbStrTable.insert(*ExpectedString);
1175}
1176
1177void DebugSHandler::handleDebugS(lld::coff::SectionChunk &DebugS) {
1178 DebugSubsectionArray Subsections;
1179
1180 ArrayRef<uint8_t> RelocatedDebugContents = consumeDebugMagic(
1181 relocateDebugChunk(Linker.Alloc, DebugS), DebugS.getSectionName());
1182
1183 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
1184 ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
1185
1186 for (const DebugSubsectionRecord &SS : Subsections) {
1187 switch (SS.kind()) {
1188 case DebugSubsectionKind::StringTable: {
1189 assert(!CVStrTab.valid() &&
1190 "Encountered multiple string table subsections!");
1191 ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
1192 break;
1193 }
1194 case DebugSubsectionKind::FileChecksums:
1195 assert(!Checksums.valid() &&
1196 "Encountered multiple checksum subsections!");
1197 ExitOnErr(Checksums.initialize(SS.getRecordData()));
1198 break;
1199 case DebugSubsectionKind::Lines:
1200 // We can add the relocated line table directly to the PDB without
1201 // modification because the file checksum offsets will stay the same.
1202 File.ModuleDBI->addDebugSubsection(SS);
1203 break;
1204 case DebugSubsectionKind::FrameData: {
1205 // We need to re-write string table indices here, so save off all
1206 // frame data subsections until we've processed the entire list of
1207 // subsections so that we can be sure we have the string table.
1208 DebugFrameDataSubsectionRef FDS;
1209 ExitOnErr(FDS.initialize(SS.getRecordData()));
1210 NewFpoFrames.push_back(std::move(FDS));
1211 break;
1212 }
1213 case DebugSubsectionKind::Symbols: {
1214 Linker.mergeSymbolRecords(&File, IndexMap, StringTableReferences,
1215 SS.getRecordData());
1216 break;
1217 }
1218 default:
1219 // FIXME: Process the rest of the subsections.
1220 break;
1221 }
1222 }
1223}
1224
1225void DebugSHandler::finish() {
1226 pdb::DbiStreamBuilder &DbiBuilder = Linker.Builder.getDbiBuilder();
1227
1228 // We should have seen all debug subsections across the entire object file now
1229 // which means that if a StringTable subsection and Checksums subsection were
1230 // present, now is the time to handle them.
1231 if (!CVStrTab.valid()) {
1232 if (Checksums.valid())
1233 fatal(".debug$S sections with a checksums subsection must also contain a "
1234 "string table subsection");
1235
1236 if (!StringTableReferences.empty())
1237 warn("No StringTable subsection was encountered, but there are string "
1238 "table references");
1239 return;
1240 }
1241
1242 // Rewrite string table indices in the Fpo Data and symbol records to refer to
1243 // the global PDB string table instead of the object file string table.
1244 for (DebugFrameDataSubsectionRef &FDS : NewFpoFrames) {
1245 const ulittle32_t *Reloc = FDS.getRelocPtr();
1246 for (codeview::FrameData FD : FDS) {
1247 FD.RvaStart += *Reloc;
1248 FD.FrameFunc =
1249 translateStringTableIndex(FD.FrameFunc, CVStrTab, Linker.PDBStrTab);
1250 DbiBuilder.addNewFpoData(FD);
1251 }
1252 }
1253
1254 for (ulittle32_t *Ref : StringTableReferences)
1255 *Ref = translateStringTableIndex(*Ref, CVStrTab, Linker.PDBStrTab);
1256
1257 // Make a new file checksum table that refers to offsets in the PDB-wide
1258 // string table. Generally the string table subsection appears after the
1259 // checksum table, so we have to do this after looping over all the
1260 // subsections.
1261 auto NewChecksums = make_unique<DebugChecksumsSubsection>(Linker.PDBStrTab);
1262 for (FileChecksumEntry &FC : Checksums) {
1263 SmallString<128> FileName =
1264 ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
1265 pdbMakeAbsolute(FileName);
1266 ExitOnErr(Linker.Builder.getDbiBuilder().addModuleSourceFile(
1267 *File.ModuleDBI, FileName));
1268 NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
1269 }
1270 File.ModuleDBI->addDebugSubsection(std::move(NewChecksums));
1271}
1272
1273void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) {
1274 if (File->wasProcessedForPDB())
1275 return;
807 // Add a module descriptor for every object file. We need to put an absolute1276 // Add a module descriptor for every object file. We need to put an absolute
808 // path to the object into the PDB. If this is a plain object, we make its1277 // path to the object into the PDB. If this is a plain object, we make its
809 // path absolute. If it's an object in an archive, we make the archive path1278 // path absolute. If it's an object in an archive, we make the archive path
810 // absolute.1279 // absolute.
811 bool InArchive = !File->ParentName.empty();1280 bool InArchive = !File->ParentName.empty();
812 SmallString<128> Path = InArchive ? File->ParentName : File->getName();1281 SmallString<128> Path = InArchive ? File->ParentName : File->getName();
813 sys::fs::make_absolute(Path);1282 pdbMakeAbsolute(Path);
814 sys::path::native(Path, sys::path::Style::windows);
815 StringRef Name = InArchive ? File->getName() : StringRef(Path);1283 StringRef Name = InArchive ? File->getName() : StringRef(Path);
8161284
817 File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));1285 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1286 File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(Name));
818 File->ModuleDBI->setObjFileName(Path);1287 File->ModuleDBI->setObjFileName(Path);
8191288
820 auto Chunks = File->getChunks();1289 auto Chunks = File->getChunks();
821 uint32_t Modi = File->ModuleDBI->getModuleIndex();1290 uint32_t Modi = File->ModuleDBI->getModuleIndex();
822 for (Chunk *C : Chunks) {1291 for (Chunk *C : Chunks) {
823 auto *SecChunk = dyn_cast<SectionChunk>(C);1292 auto *SecChunk = dyn_cast<SectionChunk>(C);
824 if (!SecChunk || !SecChunk->isLive())1293 if (!SecChunk || !SecChunk->Live)
825 continue;1294 continue;
826 pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);1295 pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);
827 File->ModuleDBI->setFirstSectionContrib(SC);1296 File->ModuleDBI->setFirstSectionContrib(SC);
...@@ -833,119 +1302,54 @@ void PDBLinker::addObjFile(ObjFile *File) {...@@ -833,119 +1302,54 @@ void PDBLinker::addObjFile(ObjFile *File) {
833 // the PDB first, so that we can get the map from object file type and item1302 // the PDB first, so that we can get the map from object file type and item
834 // indices to PDB type and item indices.1303 // indices to PDB type and item indices.
835 CVIndexMap ObjectIndexMap;1304 CVIndexMap ObjectIndexMap;
836 auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);1305 auto IndexMapResult =
1306 mergeDebugT(File, ExternIndexMap ? ExternIndexMap : &ObjectIndexMap);
8371307
838 // If the .debug$T sections fail to merge, assume there is no debug info.1308 // If the .debug$T sections fail to merge, assume there is no debug info.
839 if (!IndexMapResult) {1309 if (!IndexMapResult) {
840 warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +1310 if (!Config->WarnDebugInfoUnusable) {
841 toString(IndexMapResult.takeError()));1311 consumeError(IndexMapResult.takeError());
1312 return;
1313 }
1314 StringRef FileName = sys::path::filename(Path);
1315 warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" +
1316 ">>> failed to load reference " +
1317 StringRef(toString(IndexMapResult.takeError())));
842 return;1318 return;
843 }1319 }
8441320
845 const CVIndexMap &IndexMap = *IndexMapResult;
846
847 ScopedTimer T(SymbolMergingTimer);1321 ScopedTimer T(SymbolMergingTimer);
8481322
849 // Now do all live .debug$S sections.1323 DebugSHandler DSH(*this, *File, *IndexMapResult);
850 DebugStringTableSubsectionRef CVStrTab;1324 // Now do all live .debug$S and .debug$F sections.
851 DebugChecksumsSubsectionRef Checksums;
852 std::vector<ulittle32_t *> StringTableReferences;
853 for (SectionChunk *DebugChunk : File->getDebugChunks()) {1325 for (SectionChunk *DebugChunk : File->getDebugChunks()) {
854 if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")1326 if (!DebugChunk->Live || DebugChunk->getSize() == 0)
855 continue;1327 continue;
8561328
857 ArrayRef<uint8_t> RelocatedDebugContents =1329 if (DebugChunk->getSectionName() == ".debug$S") {
858 relocateDebugChunk(Alloc, DebugChunk);1330 DSH.handleDebugS(*DebugChunk);
859 if (RelocatedDebugContents.empty())
860 continue;1331 continue;
861
862 DebugSubsectionArray Subsections;
863 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
864 ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
865
866 for (const DebugSubsectionRecord &SS : Subsections) {
867 switch (SS.kind()) {
868 case DebugSubsectionKind::StringTable: {
869 assert(!CVStrTab.valid() &&
870 "Encountered multiple string table subsections!");
871 ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
872 break;
873 }
874 case DebugSubsectionKind::FileChecksums:
875 assert(!Checksums.valid() &&
876 "Encountered multiple checksum subsections!");
877 ExitOnErr(Checksums.initialize(SS.getRecordData()));
878 break;
879 case DebugSubsectionKind::Lines:
880 // We can add the relocated line table directly to the PDB without
881 // modification because the file checksum offsets will stay the same.
882 File->ModuleDBI->addDebugSubsection(SS);
883 break;
884 case DebugSubsectionKind::Symbols:
885 if (Config->DebugGHashes) {
886 mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
887 GlobalIDTable, StringTableReferences,
888 SS.getRecordData());
889 } else {
890 mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
891 IDTable, StringTableReferences,
892 SS.getRecordData());
893 }
894 break;
895 default:
896 // FIXME: Process the rest of the subsections.
897 break;
898 }
899 }1332 }
900 }
9011333
902 // We should have seen all debug subsections across the entire object file now1334 if (DebugChunk->getSectionName() == ".debug$F") {
903 // which means that if a StringTable subsection and Checksums subsection were1335 ArrayRef<uint8_t> RelocatedDebugContents =
904 // present, now is the time to handle them.1336 relocateDebugChunk(Alloc, *DebugChunk);
905 if (!CVStrTab.valid()) {
906 if (Checksums.valid())
907 fatal(".debug$S sections with a checksums subsection must also contain a "
908 "string table subsection");
9091337
910 if (!StringTableReferences.empty())1338 FixedStreamArray<object::FpoData> FpoRecords;
911 warn("No StringTable subsection was encountered, but there are string "1339 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
912 "table references");1340 uint32_t Count = RelocatedDebugContents.size() / sizeof(object::FpoData);
913 return;1341 ExitOnErr(Reader.readArray(FpoRecords, Count));
914 }
9151342
916 // Rewrite each string table reference based on the value that the string1343 // These are already relocated and don't refer to the string table, so we
917 // assumes in the final PDB.1344 // can just copy it.
918 for (ulittle32_t *Ref : StringTableReferences) {1345 for (const object::FpoData &FD : FpoRecords)
919 auto ExpectedString = CVStrTab.getString(*Ref);1346 DbiBuilder.addOldFpoData(FD);
920 if (!ExpectedString) {
921 warn("Invalid string table reference");
922 consumeError(ExpectedString.takeError());
923 continue;1347 continue;
924 }1348 }
925
926 *Ref = PDBStrTab.insert(*ExpectedString);
927 }1349 }
9281350
929 // Make a new file checksum table that refers to offsets in the PDB-wide1351 // Do any post-processing now that all .debug$S sections have been processed.
930 // string table. Generally the string table subsection appears after the1352 DSH.finish();
931 // checksum table, so we have to do this after looping over all the
932 // subsections.
933 auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab);
934 for (FileChecksumEntry &FC : Checksums) {
935 SmallString<128> FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
936 if (!sys::path::is_absolute(FileName) &&
937 !Config->PDBSourcePath.empty()) {
938 SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
939 sys::path::append(AbsoluteFileName, FileName);
940 sys::path::native(AbsoluteFileName);
941 sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true);
942 FileName = std::move(AbsoluteFileName);
943 }
944 ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI,
945 FileName));
946 NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
947 }
948 File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
949}1353}
9501354
951static PublicSym32 createPublic(Defined *Def) {1355static PublicSym32 createPublic(Defined *Def) {
...@@ -977,13 +1381,8 @@ void PDBLinker::addObjectsToPDB() {...@@ -977,13 +1381,8 @@ void PDBLinker::addObjectsToPDB() {
9771381
978 // Construct TPI and IPI stream contents.1382 // Construct TPI and IPI stream contents.
979 ScopedTimer T2(TpiStreamLayoutTimer);1383 ScopedTimer T2(TpiStreamLayoutTimer);
980 if (Config->DebugGHashes) {1384 addTypeInfo(Builder.getTpiBuilder(), getTypeTable());
981 addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable);1385 addTypeInfo(Builder.getIpiBuilder(), getIDTable());
982 addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable);
983 } else {
984 addTypeInfo(Builder.getTpiBuilder(), TypeTable);
985 addTypeInfo(Builder.getIpiBuilder(), IDTable);
986 }
987 T2.stop();1386 T2.stop();
9881387
989 ScopedTimer T3(GlobalsLayoutTimer);1388 ScopedTimer T3(GlobalsLayoutTimer);
...@@ -999,10 +1398,10 @@ void PDBLinker::addObjectsToPDB() {...@@ -999,10 +1398,10 @@ void PDBLinker::addObjectsToPDB() {
9991398
1000 if (!Publics.empty()) {1399 if (!Publics.empty()) {
1001 // Sort the public symbols and add them to the stream.1400 // Sort the public symbols and add them to the stream.
1002 std::sort(Publics.begin(), Publics.end(),1401 sort(parallel::par, Publics.begin(), Publics.end(),
1003 [](const PublicSym32 &L, const PublicSym32 &R) {1402 [](const PublicSym32 &L, const PublicSym32 &R) {
1004 return L.Name < R.Name;1403 return L.Name < R.Name;
1005 });1404 });
1006 for (const PublicSym32 &Pub : Publics)1405 for (const PublicSym32 &Pub : Publics)
1007 GsiBuilder.addPublicSymbol(Pub);1406 GsiBuilder.addPublicSymbol(Pub);
1008 }1407 }
...@@ -1037,6 +1436,32 @@ static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {...@@ -1037,6 +1436,32 @@ static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {
1037 }1436 }
1038}1437}
10391438
1439// Mimic MSVC which surrounds arguments containing whitespace with quotes.
1440// Double double-quotes are handled, so that the resulting string can be
1441// executed again on the cmd-line.
1442static std::string quote(ArrayRef<StringRef> Args) {
1443 std::string R;
1444 R.reserve(256);
1445 for (StringRef A : Args) {
1446 if (!R.empty())
1447 R.push_back(' ');
1448 bool HasWS = A.find(' ') != StringRef::npos;
1449 bool HasQ = A.find('"') != StringRef::npos;
1450 if (HasWS || HasQ)
1451 R.push_back('"');
1452 if (HasQ) {
1453 SmallVector<StringRef, 4> S;
1454 A.split(S, '"');
1455 R.append(join(S, "\"\""));
1456 } else {
1457 R.append(A);
1458 }
1459 if (HasWS || HasQ)
1460 R.push_back('"');
1461 }
1462 return R;
1463}
1464
1040static void addCommonLinkerModuleSymbols(StringRef Path,1465static void addCommonLinkerModuleSymbols(StringRef Path,
1041 pdb::DbiModuleDescriptorBuilder &Mod,1466 pdb::DbiModuleDescriptorBuilder &Mod,
1042 BumpPtrAllocator &Allocator) {1467 BumpPtrAllocator &Allocator) {
...@@ -1072,14 +1497,17 @@ static void addCommonLinkerModuleSymbols(StringRef Path,...@@ -1072,14 +1497,17 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
1072 CS.setLanguage(SourceLanguage::Link);1497 CS.setLanguage(SourceLanguage::Link);
10731498
1074 ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();1499 ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();
1075 std::string ArgStr = llvm::join(Args, " ");1500 std::string ArgStr = quote(Args);
1076 EBS.Fields.push_back("cwd");1501 EBS.Fields.push_back("cwd");
1077 SmallString<64> cwd;1502 SmallString<64> cwd;
1078 sys::fs::current_path(cwd);1503 if (Config->PDBSourcePath.empty())
1504 sys::fs::current_path(cwd);
1505 else
1506 cwd = Config->PDBSourcePath;
1079 EBS.Fields.push_back(cwd);1507 EBS.Fields.push_back(cwd);
1080 EBS.Fields.push_back("exe");1508 EBS.Fields.push_back("exe");
1081 SmallString<64> exe = Config->Argv[0];1509 SmallString<64> exe = Config->Argv[0];
1082 llvm::sys::fs::make_absolute(exe);1510 pdbMakeAbsolute(exe);
1083 EBS.Fields.push_back(exe);1511 EBS.Fields.push_back(exe);
1084 EBS.Fields.push_back("pdb");1512 EBS.Fields.push_back("pdb");
1085 EBS.Fields.push_back(Path);1513 EBS.Fields.push_back(Path);
...@@ -1111,7 +1539,7 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,...@@ -1111,7 +1539,7 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
1111void coff::createPDB(SymbolTable *Symtab,1539void coff::createPDB(SymbolTable *Symtab,
1112 ArrayRef<OutputSection *> OutputSections,1540 ArrayRef<OutputSection *> OutputSections,
1113 ArrayRef<uint8_t> SectionTable,1541 ArrayRef<uint8_t> SectionTable,
1114 const llvm::codeview::DebugInfo &BuildId) {1542 llvm::codeview::DebugInfo *BuildId) {
1115 ScopedTimer T1(TotalPdbLinkTimer);1543 ScopedTimer T1(TotalPdbLinkTimer);
1116 PDBLinker PDB(Symtab);1544 PDBLinker PDB(Symtab);
11171545
...@@ -1121,12 +1549,19 @@ void coff::createPDB(SymbolTable *Symtab,...@@ -1121,12 +1549,19 @@ void coff::createPDB(SymbolTable *Symtab,
1121 PDB.addNatvisFiles();1549 PDB.addNatvisFiles();
11221550
1123 ScopedTimer T2(DiskCommitTimer);1551 ScopedTimer T2(DiskCommitTimer);
1124 PDB.commit();1552 codeview::GUID Guid;
1553 PDB.commit(&Guid);
1554 memcpy(&BuildId->PDB70.Signature, &Guid, 16);
1125}1555}
11261556
1127void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {1557void PDBLinker::initialize(llvm::codeview::DebugInfo *BuildId) {
1128 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize1558 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
11291559
1560 BuildId->Signature.CVSignature = OMF::Signature::PDB70;
1561 // Signature is set to a hash of the PDB contents when the PDB is done.
1562 memset(BuildId->PDB70.Signature, 0, 16);
1563 BuildId->PDB70.Age = 1;
1564
1130 // Create streams in MSF for predefined streams, namely1565 // Create streams in MSF for predefined streams, namely
1131 // PDB, TPI, DBI and IPI.1566 // PDB, TPI, DBI and IPI.
1132 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)1567 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
...@@ -1134,15 +1569,12 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {...@@ -1134,15 +1569,12 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
11341569
1135 // Add an Info stream.1570 // Add an Info stream.
1136 auto &InfoBuilder = Builder.getInfoBuilder();1571 auto &InfoBuilder = Builder.getInfoBuilder();
1137 GUID uuid;
1138 memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid));
1139 InfoBuilder.setAge(BuildId.PDB70.Age);
1140 InfoBuilder.setGuid(uuid);
1141 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);1572 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
1573 InfoBuilder.setHashPDBContentsToGUID(true);
11421574
1143 // Add an empty DBI stream.1575 // Add an empty DBI stream.
1144 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();1576 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1145 DbiBuilder.setAge(BuildId.PDB70.Age);1577 DbiBuilder.setAge(BuildId->PDB70.Age);
1146 DbiBuilder.setVersionHeader(pdb::PdbDbiV70);1578 DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
1147 DbiBuilder.setMachineType(Config->Machine);1579 DbiBuilder.setMachineType(Config->Machine);
1148 // Technically we are not link.exe 14.11, but there are known cases where1580 // Technically we are not link.exe 14.11, but there are known cases where
...@@ -1157,8 +1589,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,...@@ -1157,8 +1589,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
1157 // It's not entirely clear what this is, but the * Linker * module uses it.1589 // It's not entirely clear what this is, but the * Linker * module uses it.
1158 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();1590 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1159 NativePath = Config->PDBPath;1591 NativePath = Config->PDBPath;
1160 sys::fs::make_absolute(NativePath);1592 pdbMakeAbsolute(NativePath);
1161 sys::path::native(NativePath, sys::path::Style::windows);
1162 uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);1593 uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
1163 auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));1594 auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
1164 LinkerModule.setPdbFilePathNI(PdbFilePathNI);1595 LinkerModule.setPdbFilePathNI(PdbFilePathNI);
...@@ -1167,7 +1598,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,...@@ -1167,7 +1598,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
1167 // Add section contributions. They must be ordered by ascending RVA.1598 // Add section contributions. They must be ordered by ascending RVA.
1168 for (OutputSection *OS : OutputSections) {1599 for (OutputSection *OS : OutputSections) {
1169 addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);1600 addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
1170 for (Chunk *C : OS->getChunks()) {1601 for (Chunk *C : OS->Chunks) {
1171 pdb::SectionContrib SC =1602 pdb::SectionContrib SC =
1172 createSectionContrib(C, LinkerModule.getModuleIndex());1603 createSectionContrib(C, LinkerModule.getModuleIndex());
1173 Builder.getDbiBuilder().addSectionContrib(SC);1604 Builder.getDbiBuilder().addSectionContrib(SC);
...@@ -1186,9 +1617,9 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,...@@ -1186,9 +1617,9 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
1186 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));1617 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
1187}1618}
11881619
1189void PDBLinker::commit() {1620void PDBLinker::commit(codeview::GUID *Guid) {
1190 // Write to a file.1621 // Write to a file.
1191 ExitOnErr(Builder.commit(Config->PDBPath));1622 ExitOnErr(Builder.commit(Config->PDBPath, Guid));
1192}1623}
11931624
1194static Expected<StringRef>1625static Expected<StringRef>
...@@ -1315,20 +1746,26 @@ std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,...@@ -1315,20 +1746,26 @@ std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,
1315 if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))1746 if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
1316 return {"", 0};1747 return {"", 0};
13171748
1318 uint32_t NameIndex;1749 Optional<uint32_t> NameIndex;
1319 uint32_t LineNumber;1750 Optional<uint32_t> LineNumber;
1320 for (LineColumnEntry &Entry : Lines) {1751 for (LineColumnEntry &Entry : Lines) {
1321 for (const LineNumberEntry &LN : Entry.LineNumbers) {1752 for (const LineNumberEntry &LN : Entry.LineNumbers) {
1753 LineInfo LI(LN.Flags);
1322 if (LN.Offset > OffsetInLinetable) {1754 if (LN.Offset > OffsetInLinetable) {
1755 if (!NameIndex) {
1756 NameIndex = Entry.NameIndex;
1757 LineNumber = LI.getStartLine();
1758 }
1323 StringRef Filename =1759 StringRef Filename =
1324 ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));1760 ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1325 return {Filename, LineNumber};1761 return {Filename, *LineNumber};
1326 }1762 }
1327 LineInfo LI(LN.Flags);
1328 NameIndex = Entry.NameIndex;1763 NameIndex = Entry.NameIndex;
1329 LineNumber = LI.getStartLine();1764 LineNumber = LI.getStartLine();
1330 }1765 }
1331 }1766 }
1332 StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));1767 if (!NameIndex)
1333 return {Filename, LineNumber};1768 return {"", 0};
1769 StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1770 return {Filename, *LineNumber};
1334}1771}
deps/lld/COFF/PDB.h+1-1
...@@ -28,7 +28,7 @@ class SymbolTable;...@@ -28,7 +28,7 @@ class SymbolTable;
28void createPDB(SymbolTable *Symtab,28void createPDB(SymbolTable *Symtab,
29 llvm::ArrayRef<OutputSection *> OutputSections,29 llvm::ArrayRef<OutputSection *> OutputSections,
30 llvm::ArrayRef<uint8_t> SectionTable,30 llvm::ArrayRef<uint8_t> SectionTable,
31 const llvm::codeview::DebugInfo &BuildId);31 llvm::codeview::DebugInfo *BuildId);
3232
33std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C,33std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C,
34 uint32_t Addr);34 uint32_t Addr);
deps/lld/COFF/SymbolTable.cpp+136-49
...@@ -60,16 +60,16 @@ void SymbolTable::addFile(InputFile *File) {...@@ -60,16 +60,16 @@ void SymbolTable::addFile(InputFile *File) {
60}60}
6161
62static void errorOrWarn(const Twine &S) {62static void errorOrWarn(const Twine &S) {
63 if (Config->Force)63 if (Config->ForceUnresolved)
64 warn(S);64 warn(S);
65 else65 else
66 error(S);66 error(S);
67}67}
6868
69// Returns the name of the symbol in SC whose value is <= Addr that is closest69// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
70// to Addr. This is generally the name of the global variable or function whose70// This is generally the global variable or function whose definition contains
71// definition contains Addr.71// Addr.
72static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {72static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) {
73 DefinedRegular *Candidate = nullptr;73 DefinedRegular *Candidate = nullptr;
7474
75 for (Symbol *S : SC->File->getSymbols()) {75 for (Symbol *S : SC->File->getSymbols()) {
...@@ -81,14 +81,12 @@ static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {...@@ -81,14 +81,12 @@ static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {
81 Candidate = D;81 Candidate = D;
82 }82 }
8383
84 if (!Candidate)84 return Candidate;
85 return "";
86 return Candidate->getName();
87}85}
8886
89static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {87std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
90 struct Location {88 struct Location {
91 StringRef SymName;89 Symbol *Sym;
92 std::pair<StringRef, uint32_t> FileLine;90 std::pair<StringRef, uint32_t> FileLine;
93 };91 };
94 std::vector<Location> Locations;92 std::vector<Location> Locations;
...@@ -102,14 +100,14 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {...@@ -102,14 +100,14 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
102 continue;100 continue;
103 std::pair<StringRef, uint32_t> FileLine =101 std::pair<StringRef, uint32_t> FileLine =
104 getFileLine(SC, R.VirtualAddress);102 getFileLine(SC, R.VirtualAddress);
105 StringRef SymName = getSymbolName(SC, R.VirtualAddress);103 Symbol *Sym = getSymbol(SC, R.VirtualAddress);
106 if (!FileLine.first.empty() || !SymName.empty())104 if (!FileLine.first.empty() || Sym)
107 Locations.push_back({SymName, FileLine});105 Locations.push_back({Sym, FileLine});
108 }106 }
109 }107 }
110108
111 if (Locations.empty())109 if (Locations.empty())
112 return "\n>>> referenced by " + toString(File) + "\n";110 return "\n>>> referenced by " + toString(File);
113111
114 std::string Out;112 std::string Out;
115 llvm::raw_string_ostream OS(Out);113 llvm::raw_string_ostream OS(Out);
...@@ -119,13 +117,87 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {...@@ -119,13 +117,87 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
119 OS << Loc.FileLine.first << ":" << Loc.FileLine.second117 OS << Loc.FileLine.first << ":" << Loc.FileLine.second
120 << "\n>>> ";118 << "\n>>> ";
121 OS << toString(File);119 OS << toString(File);
122 if (!Loc.SymName.empty())120 if (Loc.Sym)
123 OS << ":(" << Loc.SymName << ')';121 OS << ":(" << toString(*Loc.Sym) << ')';
124 }122 }
125 OS << '\n';
126 return OS.str();123 return OS.str();
127}124}
128125
126void SymbolTable::loadMinGWAutomaticImports() {
127 for (auto &I : SymMap) {
128 Symbol *Sym = I.second;
129 auto *Undef = dyn_cast<Undefined>(Sym);
130 if (!Undef)
131 continue;
132 if (!Sym->IsUsedInRegularObj)
133 continue;
134
135 StringRef Name = Undef->getName();
136
137 if (Name.startswith("__imp_"))
138 continue;
139 // If we have an undefined symbol, but we have a Lazy representing a
140 // symbol we could load from file, make sure to load that.
141 Lazy *L = dyn_cast_or_null<Lazy>(find(("__imp_" + Name).str()));
142 if (!L || L->PendingArchiveLoad)
143 continue;
144
145 log("Loading lazy " + L->getName() + " from " + L->File->getName() +
146 " for automatic import");
147 L->PendingArchiveLoad = true;
148 L->File->addMember(&L->Sym);
149 }
150}
151
152bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) {
153 if (Name.startswith("__imp_"))
154 return false;
155 Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str()));
156 if (!Imp)
157 return false;
158
159 // Replace the reference directly to a variable with a reference
160 // to the import address table instead. This obviously isn't right,
161 // but we mark the symbol as IsRuntimePseudoReloc, and a later pass
162 // will add runtime pseudo relocations for every relocation against
163 // this Symbol. The runtime pseudo relocation framework expects the
164 // reference itself to point at the IAT entry.
165 size_t ImpSize = 0;
166 if (isa<DefinedImportData>(Imp)) {
167 log("Automatically importing " + Name + " from " +
168 cast<DefinedImportData>(Imp)->getDLLName());
169 ImpSize = sizeof(DefinedImportData);
170 } else if (isa<DefinedRegular>(Imp)) {
171 log("Automatically importing " + Name + " from " +
172 toString(cast<DefinedRegular>(Imp)->File));
173 ImpSize = sizeof(DefinedRegular);
174 } else {
175 warn("unable to automatically import " + Name + " from " + Imp->getName() +
176 " from " + toString(cast<DefinedRegular>(Imp)->File) +
177 "; unexpected symbol type");
178 return false;
179 }
180 Sym->replaceKeepingName(Imp, ImpSize);
181 Sym->IsRuntimePseudoReloc = true;
182
183 // There may exist symbols named .refptr.<name> which only consist
184 // of a single pointer to <name>. If it turns out <name> is
185 // automatically imported, we don't need to keep the .refptr.<name>
186 // pointer at all, but redirect all accesses to it to the IAT entry
187 // for __imp_<name> instead, and drop the whole .refptr.<name> chunk.
188 DefinedRegular *Refptr =
189 dyn_cast_or_null<DefinedRegular>(find((".refptr." + Name).str()));
190 if (Refptr && Refptr->getChunk()->getSize() == Config->Wordsize) {
191 SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Refptr->getChunk());
192 if (SC && SC->Relocs.size() == 1 && *SC->symbols().begin() == Sym) {
193 log("Replacing .refptr." + Name + " with " + Imp->getName());
194 Refptr->getChunk()->Live = false;
195 Refptr->replaceKeepingName(Imp, ImpSize);
196 }
197 }
198 return true;
199}
200
129void SymbolTable::reportRemainingUndefines() {201void SymbolTable::reportRemainingUndefines() {
130 SmallPtrSet<Symbol *, 8> Undefs;202 SmallPtrSet<Symbol *, 8> Undefs;
131 DenseMap<Symbol *, Symbol *> LocalImports;203 DenseMap<Symbol *, Symbol *> LocalImports;
...@@ -169,9 +241,17 @@ void SymbolTable::reportRemainingUndefines() {...@@ -169,9 +241,17 @@ void SymbolTable::reportRemainingUndefines() {
169 }241 }
170 }242 }
171243
244 // We don't want to report missing Microsoft precompiled headers symbols.
245 // A proper message will be emitted instead in PDBLinker::aquirePrecompObj
246 if (Name.contains("_PchSym_"))
247 continue;
248
249 if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name))
250 continue;
251
172 // Remaining undefined symbols are not fatal if /force is specified.252 // Remaining undefined symbols are not fatal if /force is specified.
173 // They are replaced with dummy defined symbols.253 // They are replaced with dummy defined symbols.
174 if (Config->Force)254 if (Config->ForceUnresolved)
175 replaceSymbol<DefinedAbsolute>(Sym, Name, 0);255 replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
176 Undefs.insert(Sym);256 Undefs.insert(Sym);
177 }257 }
...@@ -181,10 +261,10 @@ void SymbolTable::reportRemainingUndefines() {...@@ -181,10 +261,10 @@ void SymbolTable::reportRemainingUndefines() {
181261
182 for (Symbol *B : Config->GCRoot) {262 for (Symbol *B : Config->GCRoot) {
183 if (Undefs.count(B))263 if (Undefs.count(B))
184 errorOrWarn("<root>: undefined symbol: " + B->getName());264 errorOrWarn("<root>: undefined symbol: " + toString(*B));
185 if (Config->WarnLocallyDefinedImported)265 if (Config->WarnLocallyDefinedImported)
186 if (Symbol *Imp = LocalImports.lookup(B))266 if (Symbol *Imp = LocalImports.lookup(B))
187 warn("<root>: locally defined symbol imported: " + Imp->getName() +267 warn("<root>: locally defined symbol imported: " + toString(*Imp) +
188 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");268 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
189 }269 }
190270
...@@ -195,34 +275,41 @@ void SymbolTable::reportRemainingUndefines() {...@@ -195,34 +275,41 @@ void SymbolTable::reportRemainingUndefines() {
195 if (!Sym)275 if (!Sym)
196 continue;276 continue;
197 if (Undefs.count(Sym))277 if (Undefs.count(Sym))
198 errorOrWarn("undefined symbol: " + Sym->getName() +278 errorOrWarn("undefined symbol: " + toString(*Sym) +
199 getSymbolLocations(File, SymIndex));279 getSymbolLocations(File, SymIndex));
200 if (Config->WarnLocallyDefinedImported)280 if (Config->WarnLocallyDefinedImported)
201 if (Symbol *Imp = LocalImports.lookup(Sym))281 if (Symbol *Imp = LocalImports.lookup(Sym))
202 warn(toString(File) + ": locally defined symbol imported: " +282 warn(toString(File) +
203 Imp->getName() + " (defined in " + toString(Imp->getFile()) +283 ": locally defined symbol imported: " + toString(*Imp) +
204 ") [LNK4217]");284 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
205 }285 }
206 }286 }
207}287}
208288
209std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {289std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
290 bool Inserted = false;
210 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];291 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
211 if (Sym)292 if (!Sym) {
212 return {Sym, false};293 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
213 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());294 Sym->IsUsedInRegularObj = false;
214 Sym->IsUsedInRegularObj = false;295 Sym->PendingArchiveLoad = false;
215 Sym->PendingArchiveLoad = false;296 Inserted = true;
216 return {Sym, true};297 }
298 return {Sym, Inserted};
299}
300
301std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
302 std::pair<Symbol *, bool> Result = insert(Name);
303 if (!File || !isa<BitcodeFile>(File))
304 Result.first->IsUsedInRegularObj = true;
305 return Result;
217}306}
218307
219Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,308Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
220 bool IsWeakAlias) {309 bool IsWeakAlias) {
221 Symbol *S;310 Symbol *S;
222 bool WasInserted;311 bool WasInserted;
223 std::tie(S, WasInserted) = insert(Name);312 std::tie(S, WasInserted) = insert(Name, F);
224 if (!F || !isa<BitcodeFile>(F))
225 S->IsUsedInRegularObj = true;
226 if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) {313 if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) {
227 replaceSymbol<Undefined>(S, Name);314 replaceSymbol<Undefined>(S, Name);
228 return S;315 return S;
...@@ -253,14 +340,20 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {...@@ -253,14 +340,20 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
253}340}
254341
255void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {342void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
256 error("duplicate symbol: " + toString(*Existing) + " in " +343 std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
257 toString(Existing->getFile()) + " and in " + toString(NewFile));344 toString(Existing->getFile()) + " and in " +
345 toString(NewFile);
346
347 if (Config->ForceMultiple)
348 warn(Msg);
349 else
350 error(Msg);
258}351}
259352
260Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {353Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
261 Symbol *S;354 Symbol *S;
262 bool WasInserted;355 bool WasInserted;
263 std::tie(S, WasInserted) = insert(N);356 std::tie(S, WasInserted) = insert(N, nullptr);
264 S->IsUsedInRegularObj = true;357 S->IsUsedInRegularObj = true;
265 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))358 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
266 replaceSymbol<DefinedAbsolute>(S, N, Sym);359 replaceSymbol<DefinedAbsolute>(S, N, Sym);
...@@ -272,7 +365,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {...@@ -272,7 +365,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
272Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {365Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
273 Symbol *S;366 Symbol *S;
274 bool WasInserted;367 bool WasInserted;
275 std::tie(S, WasInserted) = insert(N);368 std::tie(S, WasInserted) = insert(N, nullptr);
276 S->IsUsedInRegularObj = true;369 S->IsUsedInRegularObj = true;
277 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))370 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
278 replaceSymbol<DefinedAbsolute>(S, N, VA);371 replaceSymbol<DefinedAbsolute>(S, N, VA);
...@@ -284,7 +377,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {...@@ -284,7 +377,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
284Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {377Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
285 Symbol *S;378 Symbol *S;
286 bool WasInserted;379 bool WasInserted;
287 std::tie(S, WasInserted) = insert(N);380 std::tie(S, WasInserted) = insert(N, nullptr);
288 S->IsUsedInRegularObj = true;381 S->IsUsedInRegularObj = true;
289 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))382 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
290 replaceSymbol<DefinedSynthetic>(S, N, C);383 replaceSymbol<DefinedSynthetic>(S, N, C);
...@@ -298,9 +391,7 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,...@@ -298,9 +391,7 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
298 SectionChunk *C) {391 SectionChunk *C) {
299 Symbol *S;392 Symbol *S;
300 bool WasInserted;393 bool WasInserted;
301 std::tie(S, WasInserted) = insert(N);394 std::tie(S, WasInserted) = insert(N, F);
302 if (!isa<BitcodeFile>(F))
303 S->IsUsedInRegularObj = true;
304 if (WasInserted || !isa<DefinedRegular>(S))395 if (WasInserted || !isa<DefinedRegular>(S))
305 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,396 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,
306 /*IsExternal*/ true, Sym, C);397 /*IsExternal*/ true, Sym, C);
...@@ -314,9 +405,7 @@ SymbolTable::addComdat(InputFile *F, StringRef N,...@@ -314,9 +405,7 @@ SymbolTable::addComdat(InputFile *F, StringRef N,
314 const coff_symbol_generic *Sym) {405 const coff_symbol_generic *Sym) {
315 Symbol *S;406 Symbol *S;
316 bool WasInserted;407 bool WasInserted;
317 std::tie(S, WasInserted) = insert(N);408 std::tie(S, WasInserted) = insert(N, F);
318 if (!isa<BitcodeFile>(F))
319 S->IsUsedInRegularObj = true;
320 if (WasInserted || !isa<DefinedRegular>(S)) {409 if (WasInserted || !isa<DefinedRegular>(S)) {
321 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,410 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
322 /*IsExternal*/ true, Sym, nullptr);411 /*IsExternal*/ true, Sym, nullptr);
...@@ -331,9 +420,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,...@@ -331,9 +420,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
331 const coff_symbol_generic *Sym, CommonChunk *C) {420 const coff_symbol_generic *Sym, CommonChunk *C) {
332 Symbol *S;421 Symbol *S;
333 bool WasInserted;422 bool WasInserted;
334 std::tie(S, WasInserted) = insert(N);423 std::tie(S, WasInserted) = insert(N, F);
335 if (!isa<BitcodeFile>(F))
336 S->IsUsedInRegularObj = true;
337 if (WasInserted || !isa<DefinedCOFF>(S))424 if (WasInserted || !isa<DefinedCOFF>(S))
338 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);425 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
339 else if (auto *DC = dyn_cast<DefinedCommon>(S))426 else if (auto *DC = dyn_cast<DefinedCommon>(S))
...@@ -345,7 +432,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,...@@ -345,7 +432,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
345Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {432Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
346 Symbol *S;433 Symbol *S;
347 bool WasInserted;434 bool WasInserted;
348 std::tie(S, WasInserted) = insert(N);435 std::tie(S, WasInserted) = insert(N, nullptr);
349 S->IsUsedInRegularObj = true;436 S->IsUsedInRegularObj = true;
350 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {437 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
351 replaceSymbol<DefinedImportData>(S, N, F);438 replaceSymbol<DefinedImportData>(S, N, F);
...@@ -360,7 +447,7 @@ Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,...@@ -360,7 +447,7 @@ Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
360 uint16_t Machine) {447 uint16_t Machine) {
361 Symbol *S;448 Symbol *S;
362 bool WasInserted;449 bool WasInserted;
363 std::tie(S, WasInserted) = insert(Name);450 std::tie(S, WasInserted) = insert(Name, nullptr);
364 S->IsUsedInRegularObj = true;451 S->IsUsedInRegularObj = true;
365 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {452 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
366 replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);453 replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);
deps/lld/COFF/SymbolTable.h+8
...@@ -54,6 +54,9 @@ public:...@@ -54,6 +54,9 @@ public:
54 // symbols.54 // symbols.
55 void reportRemainingUndefines();55 void reportRemainingUndefines();
5656
57 void loadMinGWAutomaticImports();
58 bool handleMinGWAutomaticImport(Symbol *Sym, StringRef Name);
59
57 // Returns a list of chunks of selected symbols.60 // Returns a list of chunks of selected symbols.
58 std::vector<Chunk *> getChunks();61 std::vector<Chunk *> getChunks();
5962
...@@ -108,7 +111,10 @@ public:...@@ -108,7 +111,10 @@ public:
108 }111 }
109112
110private:113private:
114 /// Inserts symbol if not already present.
111 std::pair<Symbol *, bool> insert(StringRef Name);115 std::pair<Symbol *, bool> insert(StringRef Name);
116 /// Same as insert(Name), but also sets IsUsedInRegularObj.
117 std::pair<Symbol *, bool> insert(StringRef Name, InputFile *F);
112 StringRef findByPrefix(StringRef Prefix);118 StringRef findByPrefix(StringRef Prefix);
113119
114 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;120 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
...@@ -117,6 +123,8 @@ private:...@@ -117,6 +123,8 @@ private:
117123
118extern SymbolTable *Symtab;124extern SymbolTable *Symtab;
119125
126std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex);
127
120} // namespace coff128} // namespace coff
121} // namespace lld129} // namespace lld
122130
deps/lld/COFF/Symbols.cpp+8-1
...@@ -54,7 +54,7 @@ InputFile *Symbol::getFile() {...@@ -54,7 +54,7 @@ InputFile *Symbol::getFile() {
5454
55bool Symbol::isLive() const {55bool Symbol::isLive() const {
56 if (auto *R = dyn_cast<DefinedRegular>(this))56 if (auto *R = dyn_cast<DefinedRegular>(this))
57 return R->getChunk()->isLive();57 return R->getChunk()->Live;
58 if (auto *Imp = dyn_cast<DefinedImportData>(this))58 if (auto *Imp = dyn_cast<DefinedImportData>(this))
59 return Imp->File->Live;59 return Imp->File->Live;
60 if (auto *Imp = dyn_cast<DefinedImportThunk>(this))60 if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
...@@ -63,6 +63,13 @@ bool Symbol::isLive() const {...@@ -63,6 +63,13 @@ bool Symbol::isLive() const {
63 return true;63 return true;
64}64}
6565
66// MinGW specific.
67void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
68 StringRef OrigName = Name;
69 memcpy(this, Other, Size);
70 Name = OrigName;
71}
72
66COFFSymbolRef DefinedCOFF::getCOFFSymbol() {73COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
67 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize();74 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
68 if (SymSize == sizeof(coff_symbol16))75 if (SymSize == sizeof(coff_symbol16))
deps/lld/COFF/Symbols.h+9-5
...@@ -39,9 +39,9 @@ class Symbol {...@@ -39,9 +39,9 @@ class Symbol {
39public:39public:
40 enum Kind {40 enum Kind {
41 // The order of these is significant. We start with the regular defined41 // The order of these is significant. We start with the regular defined
42 // symbols as those are the most prevelant and the zero tag is the cheapest42 // symbols as those are the most prevalent and the zero tag is the cheapest
43 // to set. Among the defined kinds, the lower the kind is preferred over43 // to set. Among the defined kinds, the lower the kind is preferred over
44 // the higher kind when testing wether one symbol should take precedence44 // the higher kind when testing whether one symbol should take precedence
45 // over another.45 // over another.
46 DefinedRegularKind = 0,46 DefinedRegularKind = 0,
47 DefinedCommonKind,47 DefinedCommonKind,
...@@ -66,6 +66,8 @@ public:...@@ -66,6 +66,8 @@ public:
66 // Returns the symbol name.66 // Returns the symbol name.
67 StringRef getName();67 StringRef getName();
6868
69 void replaceKeepingName(Symbol *Other, size_t Size);
70
69 // Returns the file from which this symbol was created.71 // Returns the file from which this symbol was created.
70 InputFile *getFile();72 InputFile *getFile();
7173
...@@ -78,7 +80,7 @@ protected:...@@ -78,7 +80,7 @@ protected:
78 explicit Symbol(Kind K, StringRef N = "")80 explicit Symbol(Kind K, StringRef N = "")
79 : SymbolKind(K), IsExternal(true), IsCOMDAT(false),81 : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
80 WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),82 WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
81 Name(N) {}83 IsRuntimePseudoReloc(false), Name(N) {}
8284
83 const unsigned SymbolKind : 8;85 const unsigned SymbolKind : 8;
84 unsigned IsExternal : 1;86 unsigned IsExternal : 1;
...@@ -102,6 +104,8 @@ public:...@@ -102,6 +104,8 @@ public:
102 /// True if we've already added this symbol to the list of GC roots.104 /// True if we've already added this symbol to the list of GC roots.
103 unsigned IsGCRoot : 1;105 unsigned IsGCRoot : 1;
104106
107 unsigned IsRuntimePseudoReloc : 1;
108
105protected:109protected:
106 StringRef Name;110 StringRef Name;
107};111};
...@@ -331,8 +335,8 @@ private:...@@ -331,8 +335,8 @@ private:
331 Chunk *Data;335 Chunk *Data;
332};336};
333337
334// If you have a symbol "__imp_foo" in your object file, a symbol name338// If you have a symbol "foo" in your object file, a symbol name
335// "foo" becomes automatically available as a pointer to "__imp_foo".339// "__imp_foo" becomes automatically available as a pointer to "foo".
336// This class is for such automatically-created symbols.340// This class is for such automatically-created symbols.
337// Yes, this is an odd feature. We didn't intend to implement that.341// Yes, this is an odd feature. We didn't intend to implement that.
338// This is here just for compatibility with MSVC.342// This is here just for compatibility with MSVC.
deps/lld/COFF/Writer.cpp+601-148
...@@ -77,36 +77,38 @@ static const int SectorSize = 512;...@@ -77,36 +77,38 @@ static const int SectorSize = 512;
77static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram);77static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram);
78static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8");78static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8");
7979
80static const int NumberfOfDataDirectory = 16;80static const int NumberOfDataDirectory = 16;
8181
82namespace {82namespace {
8383
84class DebugDirectoryChunk : public Chunk {84class DebugDirectoryChunk : public Chunk {
85public:85public:
86 DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}86 DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
87 : Records(R), WriteRepro(WriteRepro) {}
8788
88 size_t getSize() const override {89 size_t getSize() const override {
89 return Records.size() * sizeof(debug_directory);90 return (Records.size() + int(WriteRepro)) * sizeof(debug_directory);
90 }91 }
9192
92 void writeTo(uint8_t *B) const override {93 void writeTo(uint8_t *B) const override {
93 auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);94 auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
9495
95 for (const Chunk *Record : Records) {96 for (const Chunk *Record : Records) {
96 D->Characteristics = 0;
97 D->TimeDateStamp = 0;
98 D->MajorVersion = 0;
99 D->MinorVersion = 0;
100 D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW;
101 D->SizeOfData = Record->getSize();
102 D->AddressOfRawData = Record->getRVA();
103 OutputSection *OS = Record->getOutputSection();97 OutputSection *OS = Record->getOutputSection();
104 uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());98 uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());
105 D->PointerToRawData = Offs;99 fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(),
106100 Record->getRVA(), Offs);
107 TimeDateStamps.push_back(&D->TimeDateStamp);
108 ++D;101 ++D;
109 }102 }
103
104 if (WriteRepro) {
105 // FIXME: The COFF spec allows either a 0-sized entry to just say
106 // "the timestamp field is really a hash", or a 4-byte size field
107 // followed by that many bytes containing a longer hash (with the
108 // lowest 4 bytes usually being the timestamp in little-endian order).
109 // Consider storing the full 8 bytes computed by xxHash64 here.
110 fillEntry(D, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
111 }
110 }112 }
111113
112 void setTimeDateStamp(uint32_t TimeDateStamp) {114 void setTimeDateStamp(uint32_t TimeDateStamp) {
...@@ -115,8 +117,23 @@ public:...@@ -115,8 +117,23 @@ public:
115 }117 }
116118
117private:119private:
120 void fillEntry(debug_directory *D, COFF::DebugType DebugType, size_t Size,
121 uint64_t RVA, uint64_t Offs) const {
122 D->Characteristics = 0;
123 D->TimeDateStamp = 0;
124 D->MajorVersion = 0;
125 D->MinorVersion = 0;
126 D->Type = DebugType;
127 D->SizeOfData = Size;
128 D->AddressOfRawData = RVA;
129 D->PointerToRawData = Offs;
130
131 TimeDateStamps.push_back(&D->TimeDateStamp);
132 }
133
118 mutable std::vector<support::ulittle32_t *> TimeDateStamps;134 mutable std::vector<support::ulittle32_t *> TimeDateStamps;
119 const std::vector<Chunk *> &Records;135 const std::vector<Chunk *> &Records;
136 bool WriteRepro;
120};137};
121138
122class CVDebugRecordChunk : public Chunk {139class CVDebugRecordChunk : public Chunk {
...@@ -150,14 +167,22 @@ private:...@@ -150,14 +167,22 @@ private:
150 void createSections();167 void createSections();
151 void createMiscChunks();168 void createMiscChunks();
152 void createImportTables();169 void createImportTables();
170 void appendImportThunks();
171 void locateImportTables(
172 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
153 void createExportTable();173 void createExportTable();
154 void mergeSections();174 void mergeSections();
175 void readRelocTargets();
176 void removeUnusedSections();
155 void assignAddresses();177 void assignAddresses();
178 void finalizeAddresses();
156 void removeEmptySections();179 void removeEmptySections();
157 void createSymbolAndStringTable();180 void createSymbolAndStringTable();
158 void openFile(StringRef OutputPath);181 void openFile(StringRef OutputPath);
159 template <typename PEHeaderTy> void writeHeader();182 template <typename PEHeaderTy> void writeHeader();
160 void createSEHTable();183 void createSEHTable();
184 void createRuntimePseudoRelocs();
185 void insertCtorDtorSymbols();
161 void createGuardCFTables();186 void createGuardCFTables();
162 void markSymbolsForRVATable(ObjFile *File,187 void markSymbolsForRVATable(ObjFile *File,
163 ArrayRef<SectionChunk *> SymIdxChunks,188 ArrayRef<SectionChunk *> SymIdxChunks,
...@@ -168,6 +193,7 @@ private:...@@ -168,6 +193,7 @@ private:
168 void writeSections();193 void writeSections();
169 void writeBuildId();194 void writeBuildId();
170 void sortExceptionTable();195 void sortExceptionTable();
196 void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
171197
172 llvm::Optional<coff_symbol16> createSymbol(Defined *D);198 llvm::Optional<coff_symbol16> createSymbol(Defined *D);
173 size_t addEntryToStringTable(StringRef Str);199 size_t addEntryToStringTable(StringRef Str);
...@@ -184,6 +210,10 @@ private:...@@ -184,6 +210,10 @@ private:
184 std::vector<char> Strtab;210 std::vector<char> Strtab;
185 std::vector<llvm::object::coff_symbol16> OutputSymtab;211 std::vector<llvm::object::coff_symbol16> OutputSymtab;
186 IdataContents Idata;212 IdataContents Idata;
213 Chunk *ImportTableStart = nullptr;
214 uint64_t ImportTableSize = 0;
215 Chunk *IATStart = nullptr;
216 uint64_t IATSize = 0;
187 DelayLoadContents DelayIdata;217 DelayLoadContents DelayIdata;
188 EdataContents Edata;218 EdataContents Edata;
189 bool SetNoSEHCharacteristic = false;219 bool SetNoSEHCharacteristic = false;
...@@ -191,7 +221,6 @@ private:...@@ -191,7 +221,6 @@ private:
191 DebugDirectoryChunk *DebugDirectory = nullptr;221 DebugDirectoryChunk *DebugDirectory = nullptr;
192 std::vector<Chunk *> DebugRecords;222 std::vector<Chunk *> DebugRecords;
193 CVDebugRecordChunk *BuildId = nullptr;223 CVDebugRecordChunk *BuildId = nullptr;
194 Optional<codeview::DebugInfo> PreviousBuildId;
195 ArrayRef<uint8_t> SectionTable;224 ArrayRef<uint8_t> SectionTable;
196225
197 uint64_t FileSize;226 uint64_t FileSize;
...@@ -209,6 +238,8 @@ private:...@@ -209,6 +238,8 @@ private:
209 OutputSection *DidatSec;238 OutputSection *DidatSec;
210 OutputSection *RsrcSec;239 OutputSection *RsrcSec;
211 OutputSection *RelocSec;240 OutputSection *RelocSec;
241 OutputSection *CtorsSec;
242 OutputSection *DtorsSec;
212243
213 // The first and last .pdata sections in the output file.244 // The first and last .pdata sections in the output file.
214 //245 //
...@@ -237,6 +268,11 @@ void OutputSection::addChunk(Chunk *C) {...@@ -237,6 +268,11 @@ void OutputSection::addChunk(Chunk *C) {
237 C->setOutputSection(this);268 C->setOutputSection(this);
238}269}
239270
271void OutputSection::insertChunkAtStart(Chunk *C) {
272 Chunks.insert(Chunks.begin(), C);
273 C->setOutputSection(this);
274}
275
240void OutputSection::setPermissions(uint32_t C) {276void OutputSection::setPermissions(uint32_t C) {
241 Header.Characteristics &= ~PermMask;277 Header.Characteristics &= ~PermMask;
242 Header.Characteristics |= C;278 Header.Characteristics |= C;
...@@ -267,77 +303,232 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {...@@ -267,77 +303,232 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
267} // namespace coff303} // namespace coff
268} // namespace lld304} // namespace lld
269305
270// PDBs are matched against executables using a build id which consists of three306// Check whether the target address S is in range from a relocation
271// components:307// of type RelType at address P.
272// 1. A 16-bit GUID308static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
273// 2. An age309 if (Config->Machine == ARMNT) {
274// 3. A time stamp.310 int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
275//311 switch (RelType) {
276// Debuggers and symbol servers match executables against debug info by checking312 case IMAGE_REL_ARM_BRANCH20T:
277// each of these components of the EXE/DLL against the corresponding value in313 return isInt<21>(Diff);
278// the PDB and failing a match if any of the components differ. In the case of314 case IMAGE_REL_ARM_BRANCH24T:
279// symbol servers, symbols are cached in a folder that is a function of the315 case IMAGE_REL_ARM_BLX23T:
280// GUID. As a result, in order to avoid symbol cache pollution where every316 return isInt<25>(Diff);
281// incremental build copies a new PDB to the symbol cache, we must try to re-use317 default:
282// the existing GUID if one exists, but bump the age. This way the match will318 return true;
283// fail, so the symbol cache knows to use the new PDB, but the GUID matches, so319 }
284// it overwrites the existing item in the symbol cache rather than making a new320 } else if (Config->Machine == ARM64) {
285// one.321 int64_t Diff = AbsoluteDifference(S, P) + Margin;
286static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) {322 switch (RelType) {
287 // We don't need to incrementally update a previous build id if we're not323 case IMAGE_REL_ARM64_BRANCH26:
288 // writing codeview debug info.324 return isInt<28>(Diff);
289 if (!Config->Debug)325 case IMAGE_REL_ARM64_BRANCH19:
290 return None;326 return isInt<21>(Diff);
327 case IMAGE_REL_ARM64_BRANCH14:
328 return isInt<16>(Diff);
329 default:
330 return true;
331 }
332 } else {
333 llvm_unreachable("Unexpected architecture");
334 }
335}
291336
292 auto ExpectedBinary = llvm::object::createBinary(Path);337// Return the last thunk for the given target if it is in range,
293 if (!ExpectedBinary) {338// or create a new one.
294 consumeError(ExpectedBinary.takeError());339static std::pair<Defined *, bool>
295 return None;340getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
341 uint16_t Type, int Margin) {
342 Defined *&LastThunk = LastThunks[Target->getRVA()];
343 if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin))
344 return {LastThunk, false};
345 Chunk *C;
346 switch (Config->Machine) {
347 case ARMNT:
348 C = make<RangeExtensionThunkARM>(Target);
349 break;
350 case ARM64:
351 C = make<RangeExtensionThunkARM64>(Target);
352 break;
353 default:
354 llvm_unreachable("Unexpected architecture");
296 }355 }
356 Defined *D = make<DefinedSynthetic>("", C);
357 LastThunk = D;
358 return {D, true};
359}
297360
298 auto Binary = std::move(*ExpectedBinary);361// This checks all relocations, and for any relocation which isn't in range
299 if (!Binary.getBinary()->isCOFF())362// it adds a thunk after the section chunk that contains the relocation.
300 return None;363// If the latest thunk for the specific target is in range, that is used
364// instead of creating a new thunk. All range checks are done with the
365// specified margin, to make sure that relocations that originally are in
366// range, but only barely, also get thunks - in case other added thunks makes
367// the target go out of range.
368//
369// After adding thunks, we verify that all relocations are in range (with
370// no extra margin requirements). If this failed, we restart (throwing away
371// the previously created thunks) and retry with a wider margin.
372static bool createThunks(OutputSection *OS, int Margin) {
373 bool AddressesChanged = false;
374 DenseMap<uint64_t, Defined *> LastThunks;
375 size_t ThunksSize = 0;
376 // Recheck Chunks.size() each iteration, since we can insert more
377 // elements into it.
378 for (size_t I = 0; I != OS->Chunks.size(); ++I) {
379 SectionChunk *SC = dyn_cast_or_null<SectionChunk>(OS->Chunks[I]);
380 if (!SC)
381 continue;
382 size_t ThunkInsertionSpot = I + 1;
383
384 // Try to get a good enough estimate of where new thunks will be placed.
385 // Offset this by the size of the new thunks added so far, to make the
386 // estimate slightly better.
387 size_t ThunkInsertionRVA = SC->getRVA() + SC->getSize() + ThunksSize;
388 for (size_t J = 0, E = SC->Relocs.size(); J < E; ++J) {
389 const coff_relocation &Rel = SC->Relocs[J];
390 Symbol *&RelocTarget = SC->RelocTargets[J];
391
392 // The estimate of the source address P should be pretty accurate,
393 // but we don't know whether the target Symbol address should be
394 // offset by ThunkSize or not (or by some of ThunksSize but not all of
395 // it), giving us some uncertainty once we have added one thunk.
396 uint64_t P = SC->getRVA() + Rel.VirtualAddress + ThunksSize;
397
398 Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
399 if (!Sym)
400 continue;
301401
302 std::error_code EC;402 uint64_t S = Sym->getRVA();
303 COFFObjectFile File(Binary.getBinary()->getMemoryBufferRef(), EC);
304 if (EC)
305 return None;
306403
307 // If the machine of the binary we're outputting doesn't match the machine404 if (isInRange(Rel.Type, S, P, Margin))
308 // of the existing binary, don't try to re-use the build id.405 continue;
309 if (File.is64() != Config->is64() || File.getMachine() != Config->Machine)406
310 return None;407 // If the target isn't in range, hook it up to an existing or new
408 // thunk.
409 Defined *Thunk;
410 bool WasNew;
411 std::tie(Thunk, WasNew) = getThunk(LastThunks, Sym, P, Rel.Type, Margin);
412 if (WasNew) {
413 Chunk *ThunkChunk = Thunk->getChunk();
414 ThunkChunk->setRVA(
415 ThunkInsertionRVA); // Estimate of where it will be located.
416 ThunkChunk->setOutputSection(OS);
417 OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
418 ThunkInsertionSpot++;
419 ThunksSize += ThunkChunk->getSize();
420 ThunkInsertionRVA += ThunkChunk->getSize();
421 AddressesChanged = true;
422 }
423 RelocTarget = Thunk;
424 }
425 }
426 return AddressesChanged;
427}
311428
312 for (const auto &DebugDir : File.debug_directories()) {429// Verify that all relocations are in range, with no extra margin requirements.
313 if (DebugDir.Type != IMAGE_DEBUG_TYPE_CODEVIEW)430static bool verifyRanges(const std::vector<Chunk *> Chunks) {
431 for (Chunk *C : Chunks) {
432 SectionChunk *SC = dyn_cast_or_null<SectionChunk>(C);
433 if (!SC)
314 continue;434 continue;
315435
316 const codeview::DebugInfo *ExistingDI = nullptr;436 for (size_t J = 0, E = SC->Relocs.size(); J < E; ++J) {
317 StringRef PDBFileName;437 const coff_relocation &Rel = SC->Relocs[J];
318 if (auto EC = File.getDebugPDBInfo(ExistingDI, PDBFileName)) {438 Symbol *RelocTarget = SC->RelocTargets[J];
319 (void)EC;439
320 return None;440 Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
441 if (!Sym)
442 continue;
443
444 uint64_t P = SC->getRVA() + Rel.VirtualAddress;
445 uint64_t S = Sym->getRVA();
446
447 if (!isInRange(Rel.Type, S, P, 0))
448 return false;
321 }449 }
322 // We only support writing PDBs in v70 format. So if this is not a build
323 // id that we recognize / support, ignore it.
324 if (ExistingDI->Signature.CVSignature != OMF::Signature::PDB70)
325 return None;
326 return *ExistingDI;
327 }450 }
328 return None;451 return true;
452}
453
454// Assign addresses and add thunks if necessary.
455void Writer::finalizeAddresses() {
456 assignAddresses();
457 if (Config->Machine != ARMNT && Config->Machine != ARM64)
458 return;
459
460 size_t OrigNumChunks = 0;
461 for (OutputSection *Sec : OutputSections) {
462 Sec->OrigChunks = Sec->Chunks;
463 OrigNumChunks += Sec->Chunks.size();
464 }
465
466 int Pass = 0;
467 int Margin = 1024 * 100;
468 while (true) {
469 // First check whether we need thunks at all, or if the previous pass of
470 // adding them turned out ok.
471 bool RangesOk = true;
472 size_t NumChunks = 0;
473 for (OutputSection *Sec : OutputSections) {
474 if (!verifyRanges(Sec->Chunks)) {
475 RangesOk = false;
476 break;
477 }
478 NumChunks += Sec->Chunks.size();
479 }
480 if (RangesOk) {
481 if (Pass > 0)
482 log("Added " + Twine(NumChunks - OrigNumChunks) + " thunks with " +
483 "margin " + Twine(Margin) + " in " + Twine(Pass) + " passes");
484 return;
485 }
486
487 if (Pass >= 10)
488 fatal("adding thunks hasn't converged after " + Twine(Pass) + " passes");
489
490 if (Pass > 0) {
491 // If the previous pass didn't work out, reset everything back to the
492 // original conditions before retrying with a wider margin. This should
493 // ideally never happen under real circumstances.
494 for (OutputSection *Sec : OutputSections) {
495 Sec->Chunks = Sec->OrigChunks;
496 for (Chunk *C : Sec->Chunks)
497 C->resetRelocTargets();
498 }
499 Margin *= 2;
500 }
501
502 // Try adding thunks everywhere where it is needed, with a margin
503 // to avoid things going out of range due to the added thunks.
504 bool AddressesChanged = false;
505 for (OutputSection *Sec : OutputSections)
506 AddressesChanged |= createThunks(Sec, Margin);
507 // If the verification above thought we needed thunks, we should have
508 // added some.
509 assert(AddressesChanged);
510
511 // Recalculate the layout for the whole image (and verify the ranges at
512 // the start of the next round).
513 assignAddresses();
514
515 Pass++;
516 }
329}517}
330518
331// The main function of the writer.519// The main function of the writer.
332void Writer::run() {520void Writer::run() {
333 ScopedTimer T1(CodeLayoutTimer);521 ScopedTimer T1(CodeLayoutTimer);
334522
523 createImportTables();
335 createSections();524 createSections();
336 createMiscChunks();525 createMiscChunks();
337 createImportTables();526 appendImportThunks();
338 createExportTable();527 createExportTable();
339 mergeSections();528 mergeSections();
340 assignAddresses();529 readRelocTargets();
530 removeUnusedSections();
531 finalizeAddresses();
341 removeEmptySections();532 removeEmptySections();
342 setSectionPermissions();533 setSectionPermissions();
343 createSymbolAndStringTable();534 createSymbolAndStringTable();
...@@ -346,9 +537,6 @@ void Writer::run() {...@@ -346,9 +537,6 @@ void Writer::run() {
346 fatal("image size (" + Twine(FileSize) + ") " +537 fatal("image size (" + Twine(FileSize) + ") " +
347 "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");538 "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
348539
349 // We must do this before opening the output file, as it depends on being able
350 // to read the contents of the existing output file.
351 PreviousBuildId = loadExistingBuildId(Config->OutputFile);
352 openFile(Config->OutputFile);540 openFile(Config->OutputFile);
353 if (Config->is64()) {541 if (Config->is64()) {
354 writeHeader<pe32plus_header>();542 writeHeader<pe32plus_header>();
...@@ -357,14 +545,14 @@ void Writer::run() {...@@ -357,14 +545,14 @@ void Writer::run() {
357 }545 }
358 writeSections();546 writeSections();
359 sortExceptionTable();547 sortExceptionTable();
360 writeBuildId();
361548
362 T1.stop();549 T1.stop();
363550
364 if (!Config->PDBPath.empty() && Config->Debug) {551 if (!Config->PDBPath.empty() && Config->Debug) {
365 assert(BuildId);552 assert(BuildId);
366 createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId);553 createPDB(Symtab, OutputSections, SectionTable, BuildId->BuildId);
367 }554 }
555 writeBuildId();
368556
369 writeMapFile(OutputSections);557 writeMapFile(OutputSections);
370558
...@@ -396,6 +584,110 @@ static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {...@@ -396,6 +584,110 @@ static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {
396 });584 });
397}585}
398586
587// Sort concrete section chunks from GNU import libraries.
588//
589// GNU binutils doesn't use short import files, but instead produces import
590// libraries that consist of object files, with section chunks for the .idata$*
591// sections. These are linked just as regular static libraries. Each import
592// library consists of one header object, one object file for every imported
593// symbol, and one trailer object. In order for the .idata tables/lists to
594// be formed correctly, the section chunks within each .idata$* section need
595// to be grouped by library, and sorted alphabetically within each library
596// (which makes sure the header comes first and the trailer last).
597static bool fixGnuImportChunks(
598 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
599 uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
600
601 // Make sure all .idata$* section chunks are mapped as RDATA in order to
602 // be sorted into the same sections as our own synthesized .idata chunks.
603 for (auto &Pair : Map) {
604 StringRef SectionName = Pair.first.first;
605 uint32_t OutChars = Pair.first.second;
606 if (!SectionName.startswith(".idata"))
607 continue;
608 if (OutChars == RDATA)
609 continue;
610 std::vector<Chunk *> &SrcVect = Pair.second;
611 std::vector<Chunk *> &DestVect = Map[{SectionName, RDATA}];
612 DestVect.insert(DestVect.end(), SrcVect.begin(), SrcVect.end());
613 SrcVect.clear();
614 }
615
616 bool HasIdata = false;
617 // Sort all .idata$* chunks, grouping chunks from the same library,
618 // with alphabetical ordering of the object fils within a library.
619 for (auto &Pair : Map) {
620 StringRef SectionName = Pair.first.first;
621 if (!SectionName.startswith(".idata"))
622 continue;
623
624 std::vector<Chunk *> &Chunks = Pair.second;
625 if (!Chunks.empty())
626 HasIdata = true;
627 std::stable_sort(Chunks.begin(), Chunks.end(), [&](Chunk *S, Chunk *T) {
628 SectionChunk *SC1 = dyn_cast_or_null<SectionChunk>(S);
629 SectionChunk *SC2 = dyn_cast_or_null<SectionChunk>(T);
630 if (!SC1 || !SC2) {
631 // if SC1, order them ascending. If SC2 or both null,
632 // S is not less than T.
633 return SC1 != nullptr;
634 }
635 // Make a string with "libraryname/objectfile" for sorting, achieving
636 // both grouping by library and sorting of objects within a library,
637 // at once.
638 std::string Key1 =
639 (SC1->File->ParentName + "/" + SC1->File->getName()).str();
640 std::string Key2 =
641 (SC2->File->ParentName + "/" + SC2->File->getName()).str();
642 return Key1 < Key2;
643 });
644 }
645 return HasIdata;
646}
647
648// Add generated idata chunks, for imported symbols and DLLs, and a
649// terminator in .idata$2.
650static void addSyntheticIdata(
651 IdataContents &Idata,
652 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
653 uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
654 Idata.create();
655
656 // Add the .idata content in the right section groups, to allow
657 // chunks from other linked in object files to be grouped together.
658 // See Microsoft PE/COFF spec 5.4 for details.
659 auto Add = [&](StringRef N, std::vector<Chunk *> &V) {
660 std::vector<Chunk *> &DestVect = Map[{N, RDATA}];
661 DestVect.insert(DestVect.end(), V.begin(), V.end());
662 };
663
664 // The loader assumes a specific order of data.
665 // Add each type in the correct order.
666 Add(".idata$2", Idata.Dirs);
667 Add(".idata$4", Idata.Lookups);
668 Add(".idata$5", Idata.Addresses);
669 Add(".idata$6", Idata.Hints);
670 Add(".idata$7", Idata.DLLNames);
671}
672
673// Locate the first Chunk and size of the import directory list and the
674// IAT.
675void Writer::locateImportTables(
676 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
677 uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
678 std::vector<Chunk *> &ImportTables = Map[{".idata$2", RDATA}];
679 if (!ImportTables.empty())
680 ImportTableStart = ImportTables.front();
681 for (Chunk *C : ImportTables)
682 ImportTableSize += C->getSize();
683
684 std::vector<Chunk *> &IAT = Map[{".idata$5", RDATA}];
685 if (!IAT.empty())
686 IATStart = IAT.front();
687 for (Chunk *C : IAT)
688 IATSize += C->getSize();
689}
690
399// Create output section objects and add them to OutputSections.691// Create output section objects and add them to OutputSections.
400void Writer::createSections() {692void Writer::createSections() {
401 // First, create the builtin sections.693 // First, create the builtin sections.
...@@ -429,12 +721,14 @@ void Writer::createSections() {...@@ -429,12 +721,14 @@ void Writer::createSections() {
429 DidatSec = CreateSection(".didat", DATA | R);721 DidatSec = CreateSection(".didat", DATA | R);
430 RsrcSec = CreateSection(".rsrc", DATA | R);722 RsrcSec = CreateSection(".rsrc", DATA | R);
431 RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);723 RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);
724 CtorsSec = CreateSection(".ctors", DATA | R | W);
725 DtorsSec = CreateSection(".dtors", DATA | R | W);
432726
433 // Then bin chunks by name and output characteristics.727 // Then bin chunks by name and output characteristics.
434 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;728 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
435 for (Chunk *C : Symtab->getChunks()) {729 for (Chunk *C : Symtab->getChunks()) {
436 auto *SC = dyn_cast<SectionChunk>(C);730 auto *SC = dyn_cast<SectionChunk>(C);
437 if (SC && !SC->isLive()) {731 if (SC && !SC->Live) {
438 if (Config->Verbose)732 if (Config->Verbose)
439 SC->printDiscardedMessage();733 SC->printDiscardedMessage();
440 continue;734 continue;
...@@ -442,26 +736,43 @@ void Writer::createSections() {...@@ -442,26 +736,43 @@ void Writer::createSections() {
442 Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);736 Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
443 }737 }
444738
739 // Even in non MinGW cases, we might need to link against GNU import
740 // libraries.
741 bool HasIdata = fixGnuImportChunks(Map);
742 if (!Idata.empty())
743 HasIdata = true;
744
745 if (HasIdata)
746 addSyntheticIdata(Idata, Map);
747
445 // Process an /order option.748 // Process an /order option.
446 if (!Config->Order.empty())749 if (!Config->Order.empty())
447 for (auto &Pair : Map)750 for (auto &Pair : Map)
448 sortBySectionOrder(Pair.second);751 sortBySectionOrder(Pair.second);
449752
753 if (HasIdata)
754 locateImportTables(Map);
755
450 // Then create an OutputSection for each section.756 // Then create an OutputSection for each section.
451 // '$' and all following characters in input section names are757 // '$' and all following characters in input section names are
452 // discarded when determining output section. So, .text$foo758 // discarded when determining output section. So, .text$foo
453 // contributes to .text, for example. See PE/COFF spec 3.2.759 // contributes to .text, for example. See PE/COFF spec 3.2.
454 for (auto Pair : Map) {760 for (auto &Pair : Map) {
455 StringRef Name = getOutputSectionName(Pair.first.first);761 StringRef Name = getOutputSectionName(Pair.first.first);
456 uint32_t OutChars = Pair.first.second;762 uint32_t OutChars = Pair.first.second;
457763
458 // In link.exe, there is a special case for the I386 target where .CRT764 if (Name == ".CRT") {
459 // sections are treated as if they have output characteristics DATA | R if765 // In link.exe, there is a special case for the I386 target where .CRT
460 // their characteristics are DATA | R | W. This implements the same special766 // sections are treated as if they have output characteristics DATA | R if
461 // case for all architectures.767 // their characteristics are DATA | R | W. This implements the same
462 if (Name == ".CRT")768 // special case for all architectures.
463 OutChars = DATA | R;769 OutChars = DATA | R;
464770
771 log("Processing section " + Pair.first.first + " -> " + Name);
772
773 sortCRTSectionChunks(Pair.second);
774 }
775
465 OutputSection *Sec = CreateSection(Name, OutChars);776 OutputSection *Sec = CreateSection(Name, OutChars);
466 std::vector<Chunk *> &Chunks = Pair.second;777 std::vector<Chunk *> &Chunks = Pair.second;
467 for (Chunk *C : Chunks)778 for (Chunk *C : Chunks)
...@@ -499,20 +810,20 @@ void Writer::createMiscChunks() {...@@ -499,20 +810,20 @@ void Writer::createMiscChunks() {
499 }810 }
500811
501 // Create Debug Information Chunks812 // Create Debug Information Chunks
502 if (Config->Debug) {813 OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
503 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);814 if (Config->Debug || Config->Repro) {
504815 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords, Config->Repro);
505 OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;816 DebugInfoSec->addChunk(DebugDirectory);
817 }
506818
819 if (Config->Debug) {
507 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We820 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
508 // output a PDB no matter what, and this chunk provides the only means of821 // output a PDB no matter what, and this chunk provides the only means of
509 // allowing a debugger to match a PDB and an executable. So we need it even822 // allowing a debugger to match a PDB and an executable. So we need it even
510 // if we're ultimately not going to write CodeView data to the PDB.823 // if we're ultimately not going to write CodeView data to the PDB.
511 auto *CVChunk = make<CVDebugRecordChunk>();824 BuildId = make<CVDebugRecordChunk>();
512 BuildId = CVChunk;825 DebugRecords.push_back(BuildId);
513 DebugRecords.push_back(CVChunk);
514826
515 DebugInfoSec->addChunk(DebugDirectory);
516 for (Chunk *C : DebugRecords)827 for (Chunk *C : DebugRecords)
517 DebugInfoSec->addChunk(C);828 DebugInfoSec->addChunk(C);
518 }829 }
...@@ -524,6 +835,12 @@ void Writer::createMiscChunks() {...@@ -524,6 +835,12 @@ void Writer::createMiscChunks() {
524 // Create /guard:cf tables if requested.835 // Create /guard:cf tables if requested.
525 if (Config->GuardCF != GuardCFLevel::Off)836 if (Config->GuardCF != GuardCFLevel::Off)
526 createGuardCFTables();837 createGuardCFTables();
838
839 if (Config->MinGW) {
840 createRuntimePseudoRelocs();
841
842 insertCtorDtorSymbols();
843 }
527}844}
528845
529// Create .idata section for the DLL-imported symbol table.846// Create .idata section for the DLL-imported symbol table.
...@@ -531,9 +848,6 @@ void Writer::createMiscChunks() {...@@ -531,9 +848,6 @@ void Writer::createMiscChunks() {
531// IdataContents class abstracted away the details for us,848// IdataContents class abstracted away the details for us,
532// so we just let it create chunks and add them to the section.849// so we just let it create chunks and add them to the section.
533void Writer::createImportTables() {850void Writer::createImportTables() {
534 if (ImportFile::Instances.empty())
535 return;
536
537 // Initialize DLLOrder so that import entries are ordered in851 // Initialize DLLOrder so that import entries are ordered in
538 // the same order as in the command line. (That affects DLL852 // the same order as in the command line. (That affects DLL
539 // initialization order, and this ordering is MSVC-compatible.)853 // initialization order, and this ordering is MSVC-compatible.)
...@@ -545,14 +859,6 @@ void Writer::createImportTables() {...@@ -545,14 +859,6 @@ void Writer::createImportTables() {
545 if (Config->DLLOrder.count(DLL) == 0)859 if (Config->DLLOrder.count(DLL) == 0)
546 Config->DLLOrder[DLL] = Config->DLLOrder.size();860 Config->DLLOrder[DLL] = Config->DLLOrder.size();
547861
548 if (File->ThunkSym) {
549 if (!isa<DefinedImportThunk>(File->ThunkSym))
550 fatal(toString(*File->ThunkSym) + " was replaced");
551 DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
552 if (File->ThunkLive)
553 TextSec->addChunk(Thunk->getChunk());
554 }
555
556 if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym))862 if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym))
557 fatal(toString(*File->ImpSym) + " was replaced");863 fatal(toString(*File->ImpSym) + " was replaced");
558 DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym);864 DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym);
...@@ -565,10 +871,25 @@ void Writer::createImportTables() {...@@ -565,10 +871,25 @@ void Writer::createImportTables() {
565 Idata.add(ImpSym);871 Idata.add(ImpSym);
566 }872 }
567 }873 }
874}
568875
569 if (!Idata.empty())876void Writer::appendImportThunks() {
570 for (Chunk *C : Idata.getChunks())877 if (ImportFile::Instances.empty())
571 IdataSec->addChunk(C);878 return;
879
880 for (ImportFile *File : ImportFile::Instances) {
881 if (!File->Live)
882 continue;
883
884 if (!File->ThunkSym)
885 continue;
886
887 if (!isa<DefinedImportThunk>(File->ThunkSym))
888 fatal(toString(*File->ThunkSym) + " was replaced");
889 DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
890 if (File->ThunkLive)
891 TextSec->addChunk(Thunk->getChunk());
892 }
572893
573 if (!DelayIdata.empty()) {894 if (!DelayIdata.empty()) {
574 Defined *Helper = cast<Defined>(Config->DelayLoadHelper);895 Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
...@@ -589,6 +910,21 @@ void Writer::createExportTable() {...@@ -589,6 +910,21 @@ void Writer::createExportTable() {
589 EdataSec->addChunk(C);910 EdataSec->addChunk(C);
590}911}
591912
913void Writer::removeUnusedSections() {
914 // Remove sections that we can be sure won't get content, to avoid
915 // allocating space for their section headers.
916 auto IsUnused = [this](OutputSection *S) {
917 if (S == RelocSec)
918 return false; // This section is populated later.
919 // MergeChunks have zero size at this point, as their size is finalized
920 // later. Only remove sections that have no Chunks at all.
921 return S->Chunks.empty();
922 };
923 OutputSections.erase(
924 std::remove_if(OutputSections.begin(), OutputSections.end(), IsUnused),
925 OutputSections.end());
926}
927
592// The Windows loader doesn't seem to like empty sections,928// The Windows loader doesn't seem to like empty sections,
593// so we remove them if any.929// so we remove them if any.
594void Writer::removeEmptySections() {930void Writer::removeEmptySections() {
...@@ -699,9 +1035,9 @@ void Writer::createSymbolAndStringTable() {...@@ -699,9 +1035,9 @@ void Writer::createSymbolAndStringTable() {
699}1035}
7001036
701void Writer::mergeSections() {1037void Writer::mergeSections() {
702 if (!PdataSec->getChunks().empty()) {1038 if (!PdataSec->Chunks.empty()) {
703 FirstPdata = PdataSec->getChunks().front();1039 FirstPdata = PdataSec->Chunks.front();
704 LastPdata = PdataSec->getChunks().back();1040 LastPdata = PdataSec->Chunks.back();
705 }1041 }
7061042
707 for (auto &P : Config->Merge) {1043 for (auto &P : Config->Merge) {
...@@ -729,11 +1065,18 @@ void Writer::mergeSections() {...@@ -729,11 +1065,18 @@ void Writer::mergeSections() {
729 }1065 }
730}1066}
7311067
1068// Visits all sections to initialize their relocation targets.
1069void Writer::readRelocTargets() {
1070 for (OutputSection *Sec : OutputSections)
1071 for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(),
1072 [&](Chunk *C) { C->readRelocTargets(); });
1073}
1074
732// Visits all sections to assign incremental, non-overlapping RVAs and1075// Visits all sections to assign incremental, non-overlapping RVAs and
733// file offsets.1076// file offsets.
734void Writer::assignAddresses() {1077void Writer::assignAddresses() {
735 SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +1078 SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
736 sizeof(data_directory) * NumberfOfDataDirectory +1079 sizeof(data_directory) * NumberOfDataDirectory +
737 sizeof(coff_section) * OutputSections.size();1080 sizeof(coff_section) * OutputSections.size();
738 SizeOfHeaders +=1081 SizeOfHeaders +=
739 Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);1082 Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
...@@ -746,7 +1089,7 @@ void Writer::assignAddresses() {...@@ -746,7 +1089,7 @@ void Writer::assignAddresses() {
746 addBaserels();1089 addBaserels();
747 uint64_t RawSize = 0, VirtualSize = 0;1090 uint64_t RawSize = 0, VirtualSize = 0;
748 Sec->Header.VirtualAddress = RVA;1091 Sec->Header.VirtualAddress = RVA;
749 for (Chunk *C : Sec->getChunks()) {1092 for (Chunk *C : Sec->Chunks) {
750 VirtualSize = alignTo(VirtualSize, C->Alignment);1093 VirtualSize = alignTo(VirtualSize, C->Alignment);
751 C->setRVA(RVA + VirtualSize);1094 C->setRVA(RVA + VirtualSize);
752 C->OutputSectionOff = VirtualSize;1095 C->OutputSectionOff = VirtualSize;
...@@ -808,7 +1151,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {...@@ -808,7 +1151,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
808 if (!Config->Relocatable)1151 if (!Config->Relocatable)
809 COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;1152 COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
810 COFF->SizeOfOptionalHeader =1153 COFF->SizeOfOptionalHeader =
811 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberfOfDataDirectory;1154 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberOfDataDirectory;
8121155
813 // Write PE header1156 // Write PE header
814 auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);1157 auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
...@@ -866,7 +1209,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {...@@ -866,7 +1209,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
866 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;1209 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
867 if (Config->TerminalServerAware)1210 if (Config->TerminalServerAware)
868 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;1211 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
869 PE->NumberOfRvaAndSize = NumberfOfDataDirectory;1212 PE->NumberOfRvaAndSize = NumberOfDataDirectory;
870 if (TextSec->getVirtualSize()) {1213 if (TextSec->getVirtualSize()) {
871 PE->BaseOfCode = TextSec->getRVA();1214 PE->BaseOfCode = TextSec->getRVA();
872 PE->SizeOfCode = TextSec->getRawSize();1215 PE->SizeOfCode = TextSec->getRawSize();
...@@ -875,16 +1218,18 @@ template <typename PEHeaderTy> void Writer::writeHeader() {...@@ -875,16 +1218,18 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
8751218
876 // Write data directory1219 // Write data directory
877 auto *Dir = reinterpret_cast<data_directory *>(Buf);1220 auto *Dir = reinterpret_cast<data_directory *>(Buf);
878 Buf += sizeof(*Dir) * NumberfOfDataDirectory;1221 Buf += sizeof(*Dir) * NumberOfDataDirectory;
879 if (!Config->Exports.empty()) {1222 if (!Config->Exports.empty()) {
880 Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();1223 Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();
881 Dir[EXPORT_TABLE].Size = Edata.getSize();1224 Dir[EXPORT_TABLE].Size = Edata.getSize();
882 }1225 }
883 if (!Idata.empty()) {1226 if (ImportTableStart) {
884 Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA();1227 Dir[IMPORT_TABLE].RelativeVirtualAddress = ImportTableStart->getRVA();
885 Dir[IMPORT_TABLE].Size = Idata.getDirSize();1228 Dir[IMPORT_TABLE].Size = ImportTableSize;
886 Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA();1229 }
887 Dir[IAT].Size = Idata.getIATSize();1230 if (IATStart) {
1231 Dir[IAT].RelativeVirtualAddress = IATStart->getRVA();
1232 Dir[IAT].Size = IATSize;
888 }1233 }
889 if (RsrcSec->getVirtualSize()) {1234 if (RsrcSec->getVirtualSize()) {
890 Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();1235 Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();
...@@ -907,7 +1252,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {...@@ -907,7 +1252,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
907 : sizeof(object::coff_tls_directory32);1252 : sizeof(object::coff_tls_directory32);
908 }1253 }
909 }1254 }
910 if (Config->Debug) {1255 if (DebugDirectory) {
911 Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();1256 Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
912 Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();1257 Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
913 }1258 }
...@@ -1002,6 +1347,25 @@ static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) {...@@ -1002,6 +1347,25 @@ static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) {
1002 RVASet.insert({C, Off});1347 RVASet.insert({C, Off});
1003}1348}
10041349
1350// Given a symbol, add it to the GFIDs table if it is a live, defined, function
1351// symbol in an executable section.
1352static void maybeAddAddressTakenFunction(SymbolRVASet &AddressTakenSyms,
1353 Symbol *S) {
1354 auto *D = dyn_cast_or_null<DefinedCOFF>(S);
1355
1356 // Ignore undefined symbols and references to non-functions (e.g. globals and
1357 // labels).
1358 if (!D ||
1359 D->getCOFFSymbol().getComplexType() != COFF::IMAGE_SYM_DTYPE_FUNCTION)
1360 return;
1361
1362 // Mark the symbol as address taken if it's in an executable section.
1363 Chunk *RefChunk = D->getChunk();
1364 OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
1365 if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
1366 addSymbolToRVASet(AddressTakenSyms, D);
1367}
1368
1005// Visit all relocations from all section contributions of this object file and1369// Visit all relocations from all section contributions of this object file and
1006// mark the relocation target as address-taken.1370// mark the relocation target as address-taken.
1007static void markSymbolsWithRelocations(ObjFile *File,1371static void markSymbolsWithRelocations(ObjFile *File,
...@@ -1010,21 +1374,17 @@ static void markSymbolsWithRelocations(ObjFile *File,...@@ -1010,21 +1374,17 @@ static void markSymbolsWithRelocations(ObjFile *File,
1010 // We only care about live section chunks. Common chunks and other chunks1374 // We only care about live section chunks. Common chunks and other chunks
1011 // don't generally contain relocations.1375 // don't generally contain relocations.
1012 SectionChunk *SC = dyn_cast<SectionChunk>(C);1376 SectionChunk *SC = dyn_cast<SectionChunk>(C);
1013 if (!SC || !SC->isLive())1377 if (!SC || !SC->Live)
1014 continue;1378 continue;
10151379
1016 // Look for relocations in this section against symbols in executable output1380 for (const coff_relocation &Reloc : SC->Relocs) {
1017 // sections.1381 if (Config->Machine == I386 && Reloc.Type == COFF::IMAGE_REL_I386_REL32)
1018 for (Symbol *Ref : SC->symbols()) {1382 // Ignore relative relocations on x86. On x86_64 they can't be ignored
1019 // FIXME: Do further testing to see if the relocation type matters,1383 // since they're also used to compute absolute addresses.
1020 // especially for 32-bit where taking the address of something usually1384 continue;
1021 // uses an absolute relocation instead of a relative one.1385
1022 if (auto *D = dyn_cast_or_null<Defined>(Ref)) {1386 Symbol *Ref = SC->File->getSymbol(Reloc.SymbolTableIndex);
1023 Chunk *RefChunk = D->getChunk();1387 maybeAddAddressTakenFunction(UsedSymbols, Ref);
1024 OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
1025 if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
1026 addSymbolToRVASet(UsedSymbols, D);
1027 }
1028 }1388 }
1029 }1389 }
1030}1390}
...@@ -1051,7 +1411,11 @@ void Writer::createGuardCFTables() {...@@ -1051,7 +1411,11 @@ void Writer::createGuardCFTables() {
10511411
1052 // Mark the image entry as address-taken.1412 // Mark the image entry as address-taken.
1053 if (Config->Entry)1413 if (Config->Entry)
1054 addSymbolToRVASet(AddressTakenSyms, cast<Defined>(Config->Entry));1414 maybeAddAddressTakenFunction(AddressTakenSyms, Config->Entry);
1415
1416 // Mark exported symbols in executable sections as address-taken.
1417 for (Export &E : Config->Exports)
1418 maybeAddAddressTakenFunction(AddressTakenSyms, E.Sym);
10551419
1056 // Ensure sections referenced in the gfid table are 16-byte aligned.1420 // Ensure sections referenced in the gfid table are 16-byte aligned.
1057 for (const ChunkAndOffset &C : AddressTakenSyms)1421 for (const ChunkAndOffset &C : AddressTakenSyms)
...@@ -1087,7 +1451,7 @@ void Writer::markSymbolsForRVATable(ObjFile *File,...@@ -1087,7 +1451,7 @@ void Writer::markSymbolsForRVATable(ObjFile *File,
1087 // is associated with something like a vtable and the vtable is discarded.1451 // is associated with something like a vtable and the vtable is discarded.
1088 // In this case, the associated gfids section is discarded, and we don't1452 // In this case, the associated gfids section is discarded, and we don't
1089 // mark the virtual member functions as address-taken by the vtable.1453 // mark the virtual member functions as address-taken by the vtable.
1090 if (!C->isLive())1454 if (!C->Live)
1091 continue;1455 continue;
10921456
1093 // Validate that the contents look like symbol table indices.1457 // Validate that the contents look like symbol table indices.
...@@ -1134,6 +1498,56 @@ void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,...@@ -1134,6 +1498,56 @@ void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
1134 cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4);1498 cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4);
1135}1499}
11361500
1501// MinGW specific. Gather all relocations that are imported from a DLL even
1502// though the code didn't expect it to, produce the table that the runtime
1503// uses for fixing them up, and provide the synthetic symbols that the
1504// runtime uses for finding the table.
1505void Writer::createRuntimePseudoRelocs() {
1506 std::vector<RuntimePseudoReloc> Rels;
1507
1508 for (Chunk *C : Symtab->getChunks()) {
1509 auto *SC = dyn_cast<SectionChunk>(C);
1510 if (!SC || !SC->Live)
1511 continue;
1512 SC->getRuntimePseudoRelocs(Rels);
1513 }
1514
1515 if (!Rels.empty())
1516 log("Writing " + Twine(Rels.size()) + " runtime pseudo relocations");
1517 PseudoRelocTableChunk *Table = make<PseudoRelocTableChunk>(Rels);
1518 RdataSec->addChunk(Table);
1519 EmptyChunk *EndOfList = make<EmptyChunk>();
1520 RdataSec->addChunk(EndOfList);
1521
1522 Symbol *HeadSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__");
1523 Symbol *EndSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__");
1524 replaceSymbol<DefinedSynthetic>(HeadSym, HeadSym->getName(), Table);
1525 replaceSymbol<DefinedSynthetic>(EndSym, EndSym->getName(), EndOfList);
1526}
1527
1528// MinGW specific.
1529// The MinGW .ctors and .dtors lists have sentinels at each end;
1530// a (uintptr_t)-1 at the start and a (uintptr_t)0 at the end.
1531// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
1532// and __DTOR_LIST__ respectively.
1533void Writer::insertCtorDtorSymbols() {
1534 AbsolutePointerChunk *CtorListHead = make<AbsolutePointerChunk>(-1);
1535 AbsolutePointerChunk *CtorListEnd = make<AbsolutePointerChunk>(0);
1536 AbsolutePointerChunk *DtorListHead = make<AbsolutePointerChunk>(-1);
1537 AbsolutePointerChunk *DtorListEnd = make<AbsolutePointerChunk>(0);
1538 CtorsSec->insertChunkAtStart(CtorListHead);
1539 CtorsSec->addChunk(CtorListEnd);
1540 DtorsSec->insertChunkAtStart(DtorListHead);
1541 DtorsSec->addChunk(DtorListEnd);
1542
1543 Symbol *CtorListSym = Symtab->findUnderscore("__CTOR_LIST__");
1544 Symbol *DtorListSym = Symtab->findUnderscore("__DTOR_LIST__");
1545 replaceSymbol<DefinedSynthetic>(CtorListSym, CtorListSym->getName(),
1546 CtorListHead);
1547 replaceSymbol<DefinedSynthetic>(DtorListSym, DtorListSym->getName(),
1548 DtorListHead);
1549}
1550
1137// Handles /section options to allow users to overwrite1551// Handles /section options to allow users to overwrite
1138// section attributes.1552// section attributes.
1139void Writer::setSectionPermissions() {1553void Writer::setSectionPermissions() {
...@@ -1160,7 +1574,7 @@ void Writer::writeSections() {...@@ -1160,7 +1574,7 @@ void Writer::writeSections() {
1160 // ADD instructions).1574 // ADD instructions).
1161 if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)1575 if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
1162 memset(SecBuf, 0xCC, Sec->getRawSize());1576 memset(SecBuf, 0xCC, Sec->getRawSize());
1163 for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(),1577 for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(),
1164 [&](Chunk *C) { C->writeTo(SecBuf); });1578 [&](Chunk *C) { C->writeTo(SecBuf); });
1165 }1579 }
1166}1580}
...@@ -1171,25 +1585,10 @@ void Writer::writeBuildId() {...@@ -1171,25 +1585,10 @@ void Writer::writeBuildId() {
1171 // timestamp as well as a Guid and Age of the PDB.1585 // timestamp as well as a Guid and Age of the PDB.
1172 // 2) In all cases, the PE COFF file header also contains a timestamp.1586 // 2) In all cases, the PE COFF file header also contains a timestamp.
1173 // For reproducibility, instead of a timestamp we want to use a hash of the1587 // For reproducibility, instead of a timestamp we want to use a hash of the
1174 // binary, however when building with debug info the hash needs to take into1588 // PE contents.
1175 // account the debug info, since it's possible to add blank lines to a file
1176 // which causes the debug info to change but not the generated code.
1177 //
1178 // To handle this, we first set the Guid and Age in the debug directory (but
1179 // only if we're doing a debug build). Then, we hash the binary (thus causing
1180 // the hash to change if only the debug info changes, since the Age will be
1181 // different). Finally, we write that hash into the debug directory (if
1182 // present) as well as the COFF file header (always).
1183 if (Config->Debug) {1589 if (Config->Debug) {
1184 assert(BuildId && "BuildId is not set!");1590 assert(BuildId && "BuildId is not set!");
1185 if (PreviousBuildId.hasValue()) {1591 // BuildId->BuildId was filled in when the PDB was written.
1186 *BuildId->BuildId = *PreviousBuildId;
1187 BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1;
1188 } else {
1189 BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70;
1190 BuildId->BuildId->PDB70.Age = 1;
1191 llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16);
1192 }
1193 }1592 }
11941593
1195 // At this point the only fields in the COFF file which remain unset are the1594 // At this point the only fields in the COFF file which remain unset are the
...@@ -1201,8 +1600,25 @@ void Writer::writeBuildId() {...@@ -1201,8 +1600,25 @@ void Writer::writeBuildId() {
1201 Buffer->getBufferSize());1600 Buffer->getBufferSize());
12021601
1203 uint32_t Timestamp = Config->Timestamp;1602 uint32_t Timestamp = Config->Timestamp;
1603 uint64_t Hash = 0;
1604 bool GenerateSyntheticBuildId =
1605 Config->MinGW && Config->Debug && Config->PDBPath.empty();
1606
1607 if (Config->Repro || GenerateSyntheticBuildId)
1608 Hash = xxHash64(OutputFileData);
1609
1204 if (Config->Repro)1610 if (Config->Repro)
1205 Timestamp = static_cast<uint32_t>(xxHash64(OutputFileData));1611 Timestamp = static_cast<uint32_t>(Hash);
1612
1613 if (GenerateSyntheticBuildId) {
1614 // For MinGW builds without a PDB file, we still generate a build id
1615 // to allow associating a crash dump to the executable.
1616 BuildId->BuildId->PDB70.CVSignature = OMF::Signature::PDB70;
1617 BuildId->BuildId->PDB70.Age = 1;
1618 memcpy(BuildId->BuildId->PDB70.Signature, &Hash, 8);
1619 // xxhash only gives us 8 bytes, so put some fixed data in the other half.
1620 memcpy(&BuildId->BuildId->PDB70.Signature[8], "LLD PDB.", 8);
1621 }
12061622
1207 if (DebugDirectory)1623 if (DebugDirectory)
1208 DebugDirectory->setTimeDateStamp(Timestamp);1624 DebugDirectory->setTimeDateStamp(Timestamp);
...@@ -1240,6 +1656,42 @@ void Writer::sortExceptionTable() {...@@ -1240,6 +1656,42 @@ void Writer::sortExceptionTable() {
1240 errs() << "warning: don't know how to handle .pdata.\n";1656 errs() << "warning: don't know how to handle .pdata.\n";
1241}1657}
12421658
1659// The CRT section contains, among other things, the array of function
1660// pointers that initialize every global variable that is not trivially
1661// constructed. The CRT calls them one after the other prior to invoking
1662// main().
1663//
1664// As per C++ spec, 3.6.2/2.3,
1665// "Variables with ordered initialization defined within a single
1666// translation unit shall be initialized in the order of their definitions
1667// in the translation unit"
1668//
1669// It is therefore critical to sort the chunks containing the function
1670// pointers in the order that they are listed in the object file (top to
1671// bottom), otherwise global objects might not be initialized in the
1672// correct order.
1673void Writer::sortCRTSectionChunks(std::vector<Chunk *> &Chunks) {
1674 auto SectionChunkOrder = [](const Chunk *A, const Chunk *B) {
1675 auto SA = dyn_cast<SectionChunk>(A);
1676 auto SB = dyn_cast<SectionChunk>(B);
1677 assert(SA && SB && "Non-section chunks in CRT section!");
1678
1679 StringRef SAObj = SA->File->MB.getBufferIdentifier();
1680 StringRef SBObj = SB->File->MB.getBufferIdentifier();
1681
1682 return SAObj == SBObj && SA->getSectionNumber() < SB->getSectionNumber();
1683 };
1684 std::stable_sort(Chunks.begin(), Chunks.end(), SectionChunkOrder);
1685
1686 if (Config->Verbose) {
1687 for (auto &C : Chunks) {
1688 auto SC = dyn_cast<SectionChunk>(C);
1689 log(" " + SC->File->MB.getBufferIdentifier().str() +
1690 ", SectionID: " + Twine(SC->getSectionNumber()));
1691 }
1692 }
1693}
1694
1243OutputSection *Writer::findSection(StringRef Name) {1695OutputSection *Writer::findSection(StringRef Name) {
1244 for (OutputSection *Sec : OutputSections)1696 for (OutputSection *Sec : OutputSections)
1245 if (Sec->Name == Name)1697 if (Sec->Name == Name)
...@@ -1259,12 +1711,13 @@ uint32_t Writer::getSizeOfInitializedData() {...@@ -1259,12 +1711,13 @@ uint32_t Writer::getSizeOfInitializedData() {
1259void Writer::addBaserels() {1711void Writer::addBaserels() {
1260 if (!Config->Relocatable)1712 if (!Config->Relocatable)
1261 return;1713 return;
1714 RelocSec->Chunks.clear();
1262 std::vector<Baserel> V;1715 std::vector<Baserel> V;
1263 for (OutputSection *Sec : OutputSections) {1716 for (OutputSection *Sec : OutputSections) {
1264 if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)1717 if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
1265 continue;1718 continue;
1266 // Collect all locations for base relocations.1719 // Collect all locations for base relocations.
1267 for (Chunk *C : Sec->getChunks())1720 for (Chunk *C : Sec->Chunks)
1268 C->getBaserels(&V);1721 C->getBaserels(&V);
1269 // Add the addresses to .reloc section.1722 // Add the addresses to .reloc section.
1270 if (!V.empty())1723 if (!V.empty())
deps/lld/COFF/Writer.h+4-2
...@@ -34,8 +34,8 @@ public:...@@ -34,8 +34,8 @@ public:
34 Header.Characteristics = Chars;34 Header.Characteristics = Chars;
35 }35 }
36 void addChunk(Chunk *C);36 void addChunk(Chunk *C);
37 void insertChunkAtStart(Chunk *C);
37 void merge(OutputSection *Other);38 void merge(OutputSection *Other);
38 ArrayRef<Chunk *> getChunks() { return Chunks; }
39 void addPermissions(uint32_t C);39 void addPermissions(uint32_t C);
40 void setPermissions(uint32_t C);40 void setPermissions(uint32_t C);
41 uint64_t getRVA() { return Header.VirtualAddress; }41 uint64_t getRVA() { return Header.VirtualAddress; }
...@@ -62,9 +62,11 @@ public:...@@ -62,9 +62,11 @@ public:
62 llvm::StringRef Name;62 llvm::StringRef Name;
63 llvm::object::coff_section Header = {};63 llvm::object::coff_section Header = {};
6464
65 std::vector<Chunk *> Chunks;
66 std::vector<Chunk *> OrigChunks;
67
65private:68private:
66 uint32_t StringTableOff = 0;69 uint32_t StringTableOff = 0;
67 std::vector<Chunk *> Chunks;
68};70};
6971
70}72}
deps/lld/Common/Args.cpp+8-1
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13#include "llvm/ADT/StringExtras.h"13#include "llvm/ADT/StringExtras.h"
14#include "llvm/ADT/StringRef.h"14#include "llvm/ADT/StringRef.h"
15#include "llvm/Option/ArgList.h"15#include "llvm/Option/ArgList.h"
16#include "llvm/Support/Path.h"
1617
17using namespace llvm;18using namespace llvm;
18using namespace lld;19using namespace lld;
...@@ -40,7 +41,7 @@ std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {...@@ -40,7 +41,7 @@ std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {
4041
41uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id,42uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id,
42 StringRef Key, uint64_t Default) {43 StringRef Key, uint64_t Default) {
43 for (auto *Arg : Args.filtered(Id)) {44 for (auto *Arg : Args.filtered_reverse(Id)) {
44 std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');45 std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
45 if (KV.first == Key) {46 if (KV.first == Key) {
46 uint64_t Result = Default;47 uint64_t Result = Default;
...@@ -64,3 +65,9 @@ std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) {...@@ -64,3 +65,9 @@ std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) {
64 }65 }
65 return Ret;66 return Ret;
66}67}
68
69StringRef lld::args::getFilenameWithoutExe(StringRef Path) {
70 if (Path.endswith_lower(".exe"))
71 return sys::path::stem(Path);
72 return sys::path::filename(Path);
73}
deps/lld/Common/ErrorHandler.cpp+3-2
...@@ -47,8 +47,9 @@ ErrorHandler &lld::errorHandler() {...@@ -47,8 +47,9 @@ ErrorHandler &lld::errorHandler() {
47}47}
4848
49void lld::exitLld(int Val) {49void lld::exitLld(int Val) {
50 // Delete the output buffer so that any tempory file is deleted.50 // Delete any temporary file, while keeping the memory mapping open.
51 errorHandler().OutputBuffer.reset();51 if (errorHandler().OutputBuffer)
52 errorHandler().OutputBuffer->discard();
5253
53 // Dealloc/destroy ManagedStatic variables before calling54 // Dealloc/destroy ManagedStatic variables before calling
54 // _exit(). In a non-LTO build, this is a nop. In an LTO55 // _exit(). In a non-LTO build, this is a nop. In an LTO
deps/lld/Common/Strings.cpp+14-19
...@@ -16,14 +16,6 @@...@@ -16,14 +16,6 @@
16#include <mutex>16#include <mutex>
17#include <vector>17#include <vector>
1818
19#if defined(_MSC_VER)
20#include <Windows.h>
21
22// DbgHelp.h must be included after Windows.h.
23#include <DbgHelp.h>
24#pragma comment(lib, "dbghelp.lib")
25#endif
26
27using namespace llvm;19using namespace llvm;
28using namespace lld;20using namespace lld;
2921
...@@ -45,18 +37,21 @@ Optional<std::string> lld::demangleItanium(StringRef Name) {...@@ -45,18 +37,21 @@ Optional<std::string> lld::demangleItanium(StringRef Name) {
45 return S;37 return S;
46}38}
4739
48Optional<std::string> lld::demangleMSVC(StringRef S) {40Optional<std::string> lld::demangleMSVC(StringRef Name) {
49#if defined(_MSC_VER)41 std::string Prefix;
50 // UnDecorateSymbolName is not thread-safe, so we need a mutex.42 if (Name.consume_front("__imp_"))
51 static std::mutex Mu;43 Prefix = "__declspec(dllimport) ";
52 std::lock_guard<std::mutex> Lock(Mu);44
45 // Demangle only C++ names.
46 if (!Name.startswith("?"))
47 return None;
5348
54 char Buf[4096];49 char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
55 if (S.startswith("?"))50 if (!Buf)
56 if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))51 return None;
57 return std::string(Buf, Len);52 std::string S(Buf);
58#endif53 free(Buf);
59 return None;54 return Prefix + S;
60}55}
6156
62StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {57StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
deps/lld/Common/TargetOptionsCommandFlags.cpp+1
...@@ -32,3 +32,4 @@ llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {...@@ -32,3 +32,4 @@ llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {
32}32}
3333
34std::string lld::GetCPUStr() { return ::getCPUStr(); }34std::string lld::GetCPUStr() { return ::getCPUStr(); }
35std::vector<std::string> lld::GetMAttrs() { return ::MAttrs; }
deps/lld/ELF/AArch64ErrataFix.cpp+16-11
...@@ -356,7 +356,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,...@@ -356,7 +356,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,
356 }356 }
357357
358 uint64_t PatchOff = 0;358 uint64_t PatchOff = 0;
359 const uint8_t *Buf = IS->Data.begin();359 const uint8_t *Buf = IS->data().begin();
360 const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);360 const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
361 uint32_t Instr1 = *InstBuf++;361 uint32_t Instr1 = *InstBuf++;
362 uint32_t Instr2 = *InstBuf++;362 uint32_t Instr2 = *InstBuf++;
...@@ -411,7 +411,7 @@ uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {...@@ -411,7 +411,7 @@ uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {
411void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {411void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {
412 // Copy the instruction that we will be replacing with a branch in the412 // Copy the instruction that we will be replacing with a branch in the
413 // Patchee Section.413 // Patchee Section.
414 write32le(Buf, read32le(Patchee->Data.begin() + PatcheeOffset));414 write32le(Buf, read32le(Patchee->data().begin() + PatcheeOffset));
415415
416 // Apply any relocation transferred from the original PatcheeSection.416 // Apply any relocation transferred from the original PatcheeSection.
417 // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc417 // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc
...@@ -451,7 +451,7 @@ void AArch64Err843419Patcher::init() {...@@ -451,7 +451,7 @@ void AArch64Err843419Patcher::init() {
451 continue;451 continue;
452 if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))452 if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))
453 continue;453 continue;
454 if (auto *Sec = dyn_cast<InputSection>(Def->Section))454 if (auto *Sec = dyn_cast_or_null<InputSection>(Def->Section))
455 if (Sec->Flags & SHF_EXECINSTR)455 if (Sec->Flags & SHF_EXECINSTR)
456 SectionMap[Sec].push_back(Def);456 SectionMap[Sec].push_back(Def);
457 }457 }
...@@ -487,7 +487,8 @@ void AArch64Err843419Patcher::insertPatches(...@@ -487,7 +487,8 @@ void AArch64Err843419Patcher::insertPatches(
487 InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {487 InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
488 uint64_t ISLimit;488 uint64_t ISLimit;
489 uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;489 uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;
490 uint64_t PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;490 uint64_t PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
491 uint64_t OutSecAddr = ISD.Sections.front()->getParent()->Addr;
491492
492 // Set the OutSecOff of patches to the place where we want to insert them.493 // Set the OutSecOff of patches to the place where we want to insert them.
493 // We use a similar strategy to Thunk placement. Place patches roughly494 // We use a similar strategy to Thunk placement. Place patches roughly
...@@ -498,12 +499,12 @@ void AArch64Err843419Patcher::insertPatches(...@@ -498,12 +499,12 @@ void AArch64Err843419Patcher::insertPatches(
498 ISLimit = IS->OutSecOff + IS->getSize();499 ISLimit = IS->OutSecOff + IS->getSize();
499 if (ISLimit > PatchUpperBound) {500 if (ISLimit > PatchUpperBound) {
500 while (PatchIt != PatchEnd) {501 while (PatchIt != PatchEnd) {
501 if ((*PatchIt)->getLDSTAddr() >= PrevISLimit)502 if ((*PatchIt)->getLDSTAddr() - OutSecAddr >= PrevISLimit)
502 break;503 break;
503 (*PatchIt)->OutSecOff = PrevISLimit;504 (*PatchIt)->OutSecOff = PrevISLimit;
504 ++PatchIt;505 ++PatchIt;
505 }506 }
506 PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;507 PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
507 }508 }
508 PrevISLimit = ISLimit;509 PrevISLimit = ISLimit;
509 }510 }
...@@ -538,20 +539,24 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,...@@ -538,20 +539,24 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
538 InputSection *IS,539 InputSection *IS,
539 std::vector<Patch843419Section *> &Patches) {540 std::vector<Patch843419Section *> &Patches) {
540 // There may be a relocation at the same offset that we are patching. There541 // There may be a relocation at the same offset that we are patching. There
541 // are three cases that we need to consider.542 // are four cases that we need to consider.
542 // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this543 // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this
543 // instance of the erratum on a previous patch and altered the relocation. We544 // instance of the erratum on a previous patch and altered the relocation. We
544 // have nothing more to do.545 // have nothing more to do.
545 // Case 2: A load/store register (unsigned immediate) class relocation. There546 // Case 2: A TLS Relaxation R_RELAX_TLS_IE_TO_LE. In this case the ADRP that
547 // we read will be transformed into a MOVZ later so we actually don't match
548 // the sequence and have nothing more to do.
549 // Case 3: A load/store register (unsigned immediate) class relocation. There
546 // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and550 // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and
547 // they are both absolute. We need to add the same relocation to the patch,551 // they are both absolute. We need to add the same relocation to the patch,
548 // and replace the relocation with a R_AARCH_JUMP26 branch relocation.552 // and replace the relocation with a R_AARCH_JUMP26 branch relocation.
549 // Case 3: No relocation. We must create a new R_AARCH64_JUMP26 branch553 // Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
550 // relocation at the offset.554 // relocation at the offset.
551 auto RelIt = std::find_if(555 auto RelIt = std::find_if(
552 IS->Relocations.begin(), IS->Relocations.end(),556 IS->Relocations.begin(), IS->Relocations.end(),
553 [=](const Relocation &R) { return R.Offset == PatcheeOffset; });557 [=](const Relocation &R) { return R.Offset == PatcheeOffset; });
554 if (RelIt != IS->Relocations.end() && RelIt->Type == R_AARCH64_JUMP26)558 if (RelIt != IS->Relocations.end() &&
559 (RelIt->Type == R_AARCH64_JUMP26 || RelIt->Expr == R_RELAX_TLS_IE_TO_LE))
555 return;560 return;
556561
557 log("detected cortex-a53-843419 erratum sequence starting at " +562 log("detected cortex-a53-843419 erratum sequence starting at " +
...@@ -598,7 +603,7 @@ AArch64Err843419Patcher::patchInputSectionDescription(...@@ -598,7 +603,7 @@ AArch64Err843419Patcher::patchInputSectionDescription(
598 auto DataSym = std::next(CodeSym);603 auto DataSym = std::next(CodeSym);
599 uint64_t Off = (*CodeSym)->Value;604 uint64_t Off = (*CodeSym)->Value;
600 uint64_t Limit =605 uint64_t Limit =
601 (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value;606 (DataSym == MapSyms.end()) ? IS->data().size() : (*DataSym)->Value;
602607
603 while (Off < Limit) {608 while (Off < Limit) {
604 uint64_t StartAddr = IS->getVA(Off);609 uint64_t StartAddr = IS->getVA(Off);
deps/lld/ELF/Arch/AArch64.cpp+21-16
...@@ -41,6 +41,7 @@ public:...@@ -41,6 +41,7 @@ public:
41 int32_t Index, unsigned RelOff) const override;41 int32_t Index, unsigned RelOff) const override;
42 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,42 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
43 uint64_t BranchAddr, const Symbol &S) const override;43 uint64_t BranchAddr, const Symbol &S) const override;
44 uint32_t getThunkSectionSpacing() const override;
44 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;45 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
45 bool usesOnlyLowPageBits(RelType Type) const override;46 bool usesOnlyLowPageBits(RelType Type) const override;
46 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;47 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
...@@ -57,6 +58,7 @@ AArch64::AArch64() {...@@ -57,6 +58,7 @@ AArch64::AArch64() {
57 RelativeRel = R_AARCH64_RELATIVE;58 RelativeRel = R_AARCH64_RELATIVE;
58 IRelativeRel = R_AARCH64_IRELATIVE;59 IRelativeRel = R_AARCH64_IRELATIVE;
59 GotRel = R_AARCH64_GLOB_DAT;60 GotRel = R_AARCH64_GLOB_DAT;
61 NoneRel = R_AARCH64_NONE;
60 PltRel = R_AARCH64_JUMP_SLOT;62 PltRel = R_AARCH64_JUMP_SLOT;
61 TlsDescRel = R_AARCH64_TLSDESC;63 TlsDescRel = R_AARCH64_TLSDESC;
62 TlsGotRel = R_AARCH64_TLS_TPREL64;64 TlsGotRel = R_AARCH64_TLS_TPREL64;
...@@ -66,22 +68,18 @@ AArch64::AArch64() {...@@ -66,22 +68,18 @@ AArch64::AArch64() {
66 PltHeaderSize = 32;68 PltHeaderSize = 32;
67 DefaultMaxPageSize = 65536;69 DefaultMaxPageSize = 65536;
6870
69 // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant71 // Align to the 2 MiB page size (known as a superpage or huge page).
70 // 1 of the tls structures and the tcb size is 16.72 // FreeBSD automatically promotes 2 MiB-aligned allocations.
71 TcbSize = 16;73 DefaultImageBase = 0x200000;
72 NeedsThunks = true;
7374
74 // See comment in Arch/ARM.cpp for a more detailed explanation of75 NeedsThunks = true;
75 // ThunkSectionSpacing. For AArch64 the only branches we are permitted to
76 // Thunk have a range of +/- 128 MiB
77 ThunkSectionSpacing = (128 * 1024 * 1024) - 0x30000;
78}76}
7977
80RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,78RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
81 const uint8_t *Loc) const {79 const uint8_t *Loc) const {
82 switch (Type) {80 switch (Type) {
83 case R_AARCH64_TLSDESC_ADR_PAGE21:81 case R_AARCH64_TLSDESC_ADR_PAGE21:
84 return R_TLSDESC_PAGE;82 return R_AARCH64_TLSDESC_PAGE;
85 case R_AARCH64_TLSDESC_LD64_LO12:83 case R_AARCH64_TLSDESC_LD64_LO12:
86 case R_AARCH64_TLSDESC_ADD_LO12:84 case R_AARCH64_TLSDESC_ADD_LO12:
87 return R_TLSDESC;85 return R_TLSDESC;
...@@ -107,13 +105,13 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,...@@ -107,13 +105,13 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
107 case R_AARCH64_LD_PREL_LO19:105 case R_AARCH64_LD_PREL_LO19:
108 return R_PC;106 return R_PC;
109 case R_AARCH64_ADR_PREL_PG_HI21:107 case R_AARCH64_ADR_PREL_PG_HI21:
110 return R_PAGE_PC;108 return R_AARCH64_PAGE_PC;
111 case R_AARCH64_LD64_GOT_LO12_NC:109 case R_AARCH64_LD64_GOT_LO12_NC:
112 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:110 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
113 return R_GOT;111 return R_GOT;
114 case R_AARCH64_ADR_GOT_PAGE:112 case R_AARCH64_ADR_GOT_PAGE:
115 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:113 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
116 return R_GOT_PAGE_PC;114 return R_AARCH64_GOT_PAGE_PC;
117 case R_AARCH64_NONE:115 case R_AARCH64_NONE:
118 return R_NONE;116 return R_NONE;
119 default:117 default:
...@@ -125,7 +123,7 @@ RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data,...@@ -125,7 +123,7 @@ RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
125 RelExpr Expr) const {123 RelExpr Expr) const {
126 if (Expr == R_RELAX_TLS_GD_TO_IE) {124 if (Expr == R_RELAX_TLS_GD_TO_IE) {
127 if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)125 if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
128 return R_RELAX_TLS_GD_TO_IE_PAGE_PC;126 return R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC;
129 return R_RELAX_TLS_GD_TO_IE_ABS;127 return R_RELAX_TLS_GD_TO_IE_ABS;
130 }128 }
131 return Expr;129 return Expr;
...@@ -156,7 +154,7 @@ RelType AArch64::getDynRel(RelType Type) const {...@@ -156,7 +154,7 @@ RelType AArch64::getDynRel(RelType Type) const {
156}154}
157155
158void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {156void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
159 write64le(Buf, InX::Plt->getVA());157 write64le(Buf, In.Plt->getVA());
160}158}
161159
162void AArch64::writePltHeader(uint8_t *Buf) const {160void AArch64::writePltHeader(uint8_t *Buf) const {
...@@ -172,8 +170,8 @@ void AArch64::writePltHeader(uint8_t *Buf) const {...@@ -172,8 +170,8 @@ void AArch64::writePltHeader(uint8_t *Buf) const {
172 };170 };
173 memcpy(Buf, PltData, sizeof(PltData));171 memcpy(Buf, PltData, sizeof(PltData));
174172
175 uint64_t Got = InX::GotPlt->getVA();173 uint64_t Got = In.GotPlt->getVA();
176 uint64_t Plt = InX::Plt->getVA();174 uint64_t Plt = In.Plt->getVA();
177 relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,175 relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
178 getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));176 getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
179 relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);177 relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
...@@ -208,6 +206,13 @@ bool AArch64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,...@@ -208,6 +206,13 @@ bool AArch64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
208 return !inBranchRange(Type, BranchAddr, Dst);206 return !inBranchRange(Type, BranchAddr, Dst);
209}207}
210208
209uint32_t AArch64::getThunkSectionSpacing() const {
210 // See comment in Arch/ARM.cpp for a more detailed explanation of
211 // getThunkSectionSpacing(). For AArch64 the only branches we are permitted to
212 // Thunk have a range of +/- 128 MiB
213 return (128 * 1024 * 1024) - 0x30000;
214}
215
211bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {216bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
212 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)217 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
213 return true;218 return true;
...@@ -338,7 +343,7 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -338,7 +343,7 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
338 or32le(Loc, (Val & 0xFFFC) << 3);343 or32le(Loc, (Val & 0xFFFC) << 3);
339 break;344 break;
340 case R_AARCH64_TLSLE_ADD_TPREL_HI12:345 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
341 checkInt(Loc, Val, 24, Type);346 checkUInt(Loc, Val, 24, Type);
342 or32AArch64Imm(Loc, Val >> 12);347 or32AArch64Imm(Loc, Val >> 12);
343 break;348 break;
344 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:349 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
deps/lld/ELF/Arch/AMDGPU.cpp+1
...@@ -35,6 +35,7 @@ public:...@@ -35,6 +35,7 @@ public:
35AMDGPU::AMDGPU() {35AMDGPU::AMDGPU() {
36 RelativeRel = R_AMDGPU_RELATIVE64;36 RelativeRel = R_AMDGPU_RELATIVE64;
37 GotRel = R_AMDGPU_ABS64;37 GotRel = R_AMDGPU_ABS64;
38 NoneRel = R_AMDGPU_NONE;
38 GotEntrySize = 8;39 GotEntrySize = 8;
39}40}
4041
deps/lld/ELF/Arch/ARM.cpp+76-48
...@@ -40,6 +40,7 @@ public:...@@ -40,6 +40,7 @@ public:
40 void addPltHeaderSymbols(InputSection &ISD) const override;40 void addPltHeaderSymbols(InputSection &ISD) const override;
41 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,41 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
42 uint64_t BranchAddr, const Symbol &S) const override;42 uint64_t BranchAddr, const Symbol &S) const override;
43 uint32_t getThunkSectionSpacing() const override;
43 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;44 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
44 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;45 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
45};46};
...@@ -50,6 +51,7 @@ ARM::ARM() {...@@ -50,6 +51,7 @@ ARM::ARM() {
50 RelativeRel = R_ARM_RELATIVE;51 RelativeRel = R_ARM_RELATIVE;
51 IRelativeRel = R_ARM_IRELATIVE;52 IRelativeRel = R_ARM_IRELATIVE;
52 GotRel = R_ARM_GLOB_DAT;53 GotRel = R_ARM_GLOB_DAT;
54 NoneRel = R_ARM_NONE;
53 PltRel = R_ARM_JUMP_SLOT;55 PltRel = R_ARM_JUMP_SLOT;
54 TlsGotRel = R_ARM_TLS_TPOFF32;56 TlsGotRel = R_ARM_TLS_TPOFF32;
55 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;57 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
...@@ -59,41 +61,8 @@ ARM::ARM() {...@@ -59,41 +61,8 @@ ARM::ARM() {
59 GotPltEntrySize = 4;61 GotPltEntrySize = 4;
60 PltEntrySize = 16;62 PltEntrySize = 16;
61 PltHeaderSize = 32;63 PltHeaderSize = 32;
62 TrapInstr = 0xd4d4d4d4;64 TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
63 // ARM uses Variant 1 TLS
64 TcbSize = 8;
65 NeedsThunks = true;65 NeedsThunks = true;
66
67 // The placing of pre-created ThunkSections is controlled by the
68 // ThunkSectionSpacing parameter. The aim is to place the
69 // ThunkSection such that all branches from the InputSections prior to the
70 // ThunkSection can reach a Thunk placed at the end of the ThunkSection.
71 // Graphically:
72 // | up to ThunkSectionSpacing .text input sections |
73 // | ThunkSection |
74 // | up to ThunkSectionSpacing .text input sections |
75 // | ThunkSection |
76
77 // Pre-created ThunkSections are spaced roughly 16MiB apart on ARM. This is to
78 // match the most common expected case of a Thumb 2 encoded BL, BLX or B.W
79 // ARM B, BL, BLX range +/- 32MiB
80 // Thumb B.W, BL, BLX range +/- 16MiB
81 // Thumb B<cc>.W range +/- 1MiB
82 // If a branch cannot reach a pre-created ThunkSection a new one will be
83 // created so we can handle the rare cases of a Thumb 2 conditional branch.
84 // We intentionally use a lower size for ThunkSectionSpacing than the maximum
85 // branch range so the end of the ThunkSection is more likely to be within
86 // range of the branch instruction that is furthest away. The value we shorten
87 // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
88 // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
89 // one of the Thunks going out of range.
90
91 // FIXME: lld assumes that the Thumb BL and BLX encoding permits the J1 and
92 // J2 bits to be used to extend the branch range. On earlier Architectures
93 // such as ARMv4, ARMv5 and ARMv6 (except ARMv6T2) the range is +/- 4MiB. If
94 // support for the earlier encodings is added then when they are used the
95 // ThunkSectionSpacing will need lowering.
96 ThunkSectionSpacing = 0x1000000 - 0x30000;
97}66}
9867
99uint32_t ARM::calcEFlags() const {68uint32_t ARM::calcEFlags() const {
...@@ -165,6 +134,12 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,...@@ -165,6 +134,12 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
165 return R_NONE;134 return R_NONE;
166 case R_ARM_TLS_LE32:135 case R_ARM_TLS_LE32:
167 return R_TLS;136 return R_TLS;
137 case R_ARM_V4BX:
138 // V4BX is just a marker to indicate there's a "bx rN" instruction at the
139 // given address. It can be used to implement a special linker mode which
140 // rewrites ARMv4T inputs to ARMv4. Since we support only ARMv4 input and
141 // not ARMv4 output, we can just ignore it.
142 return R_HINT;
168 default:143 default:
169 return R_ABS;144 return R_ABS;
170 }145 }
...@@ -177,7 +152,7 @@ RelType ARM::getDynRel(RelType Type) const {...@@ -177,7 +152,7 @@ RelType ARM::getDynRel(RelType Type) const {
177}152}
178153
179void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {154void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
180 write32le(Buf, InX::Plt->getVA());155 write32le(Buf, In.Plt->getVA());
181}156}
182157
183void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {158void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
...@@ -198,8 +173,8 @@ static void writePltHeaderLong(uint8_t *Buf) {...@@ -198,8 +173,8 @@ static void writePltHeaderLong(uint8_t *Buf) {
198 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary173 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
199 0xd4, 0xd4, 0xd4, 0xd4};174 0xd4, 0xd4, 0xd4, 0xd4};
200 memcpy(Buf, PltData, sizeof(PltData));175 memcpy(Buf, PltData, sizeof(PltData));
201 uint64_t GotPlt = InX::GotPlt->getVA();176 uint64_t GotPlt = In.GotPlt->getVA();
202 uint64_t L1 = InX::Plt->getVA() + 8;177 uint64_t L1 = In.Plt->getVA() + 8;
203 write32le(Buf + 16, GotPlt - L1 - 8);178 write32le(Buf + 16, GotPlt - L1 - 8);
204}179}
205180
...@@ -217,7 +192,7 @@ void ARM::writePltHeader(uint8_t *Buf) const {...@@ -217,7 +192,7 @@ void ARM::writePltHeader(uint8_t *Buf) const {
217 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)192 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
218 };193 };
219194
220 uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4;195 uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
221 if (!llvm::isUInt<27>(Offset)) {196 if (!llvm::isUInt<27>(Offset)) {
222 // We cannot encode the Offset, use the long form.197 // We cannot encode the Offset, use the long form.
223 writePltHeaderLong(Buf);198 writePltHeaderLong(Buf);
...@@ -227,10 +202,10 @@ void ARM::writePltHeader(uint8_t *Buf) const {...@@ -227,10 +202,10 @@ void ARM::writePltHeader(uint8_t *Buf) const {
227 write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));202 write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
228 write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));203 write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
229 write32le(Buf + 12, PltData[3] | (Offset & 0xfff));204 write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
230 write32le(Buf + 16, TrapInstr); // Pad to 32-byte boundary205 memcpy(Buf + 16, TrapInstr.data(), 4); // Pad to 32-byte boundary
231 write32le(Buf + 20, TrapInstr);206 memcpy(Buf + 20, TrapInstr.data(), 4);
232 write32le(Buf + 24, TrapInstr);207 memcpy(Buf + 24, TrapInstr.data(), 4);
233 write32le(Buf + 28, TrapInstr);208 memcpy(Buf + 28, TrapInstr.data(), 4);
234}209}
235210
236void ARM::addPltHeaderSymbols(InputSection &IS) const {211void ARM::addPltHeaderSymbols(InputSection &IS) const {
...@@ -279,7 +254,7 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,...@@ -279,7 +254,7 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
279 write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));254 write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
280 write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));255 write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
281 write32le(Buf + 8, PltData[2] | (Offset & 0xfff));256 write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
282 write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary257 memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary
283}258}
284259
285void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {260void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
...@@ -324,6 +299,40 @@ bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,...@@ -324,6 +299,40 @@ bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
324 return false;299 return false;
325}300}
326301
302uint32_t ARM::getThunkSectionSpacing() const {
303 // The placing of pre-created ThunkSections is controlled by the value
304 // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
305 // place the ThunkSection such that all branches from the InputSections
306 // prior to the ThunkSection can reach a Thunk placed at the end of the
307 // ThunkSection. Graphically:
308 // | up to ThunkSectionSpacing .text input sections |
309 // | ThunkSection |
310 // | up to ThunkSectionSpacing .text input sections |
311 // | ThunkSection |
312
313 // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
314 // is to match the most common expected case of a Thumb 2 encoded BL, BLX or
315 // B.W:
316 // ARM B, BL, BLX range +/- 32MiB
317 // Thumb B.W, BL, BLX range +/- 16MiB
318 // Thumb B<cc>.W range +/- 1MiB
319 // If a branch cannot reach a pre-created ThunkSection a new one will be
320 // created so we can handle the rare cases of a Thumb 2 conditional branch.
321 // We intentionally use a lower size for ThunkSectionSpacing than the maximum
322 // branch range so the end of the ThunkSection is more likely to be within
323 // range of the branch instruction that is furthest away. The value we shorten
324 // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
325 // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
326 // one of the Thunks going out of range.
327
328 // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch
329 // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
330 // ARMv6T2) the range is +/- 4MiB.
331
332 return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
333 : 0x400000 - 0x7500;
334}
335
327bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {336bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
328 uint64_t Range;337 uint64_t Range;
329 uint64_t InstrSize;338 uint64_t InstrSize;
...@@ -342,7 +351,7 @@ bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {...@@ -342,7 +351,7 @@ bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
342 break;351 break;
343 case R_ARM_THM_JUMP24:352 case R_ARM_THM_JUMP24:
344 case R_ARM_THM_CALL:353 case R_ARM_THM_CALL:
345 Range = 0x1000000;354 Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
346 InstrSize = 2;355 InstrSize = 2;
347 break;356 break;
348 default:357 default:
...@@ -447,11 +456,23 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -447,11 +456,23 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
447 }456 }
448 // Bit 12 is 0 for BLX, 1 for BL457 // Bit 12 is 0 for BLX, 1 for BL
449 write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);458 write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
459 if (!Config->ARMJ1J2BranchEncoding) {
460 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
461 // different encoding rules and range due to J1 and J2 always being 1.
462 checkInt(Loc, Val, 23, Type);
463 write16le(Loc,
464 0xf000 | // opcode
465 ((Val >> 12) & 0x07ff)); // imm11
466 write16le(Loc + 2,
467 (read16le(Loc + 2) & 0xd000) | // opcode
468 0x2800 | // J1 == J2 == 1
469 ((Val >> 1) & 0x07ff)); // imm11
470 break;
471 }
450 // Fall through as rest of encoding is the same as B.W472 // Fall through as rest of encoding is the same as B.W
451 LLVM_FALLTHROUGH;473 LLVM_FALLTHROUGH;
452 case R_ARM_THM_JUMP24:474 case R_ARM_THM_JUMP24:
453 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0475 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
454 // FIXME: Use of I1 and I2 require v6T2ops
455 checkInt(Loc, Val, 25, Type);476 checkInt(Loc, Val, 25, Type);
456 write16le(Loc,477 write16le(Loc,
457 0xf000 | // opcode478 0xf000 | // opcode
...@@ -470,14 +491,12 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -470,14 +491,12 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
470 break;491 break;
471 case R_ARM_MOVT_ABS:492 case R_ARM_MOVT_ABS:
472 case R_ARM_MOVT_PREL:493 case R_ARM_MOVT_PREL:
473 checkInt(Loc, Val, 32, Type);
474 write32le(Loc, (read32le(Loc) & ~0x000f0fff) |494 write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
475 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));495 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
476 break;496 break;
477 case R_ARM_THM_MOVT_ABS:497 case R_ARM_THM_MOVT_ABS:
478 case R_ARM_THM_MOVT_PREL:498 case R_ARM_THM_MOVT_PREL:
479 // Encoding T1: A = imm4:i:imm3:imm8499 // Encoding T1: A = imm4:i:imm3:imm8
480 checkInt(Loc, Val, 32, Type);
481 write16le(Loc,500 write16le(Loc,
482 0xf2c0 | // opcode501 0xf2c0 | // opcode
483 ((Val >> 17) & 0x0400) | // i502 ((Val >> 17) & 0x0400) | // i
...@@ -542,10 +561,19 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {...@@ -542,10 +561,19 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
542 ((Lo & 0x07ff) << 1)); // imm11:0561 ((Lo & 0x07ff) << 1)); // imm11:0
543 }562 }
544 case R_ARM_THM_CALL:563 case R_ARM_THM_CALL:
564 if (!Config->ARMJ1J2BranchEncoding) {
565 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
566 // different encoding rules and range due to J1 and J2 always being 1.
567 uint16_t Hi = read16le(Buf);
568 uint16_t Lo = read16le(Buf + 2);
569 return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11
570 ((Lo & 0x7ff) << 1)); // imm11:0
571 break;
572 }
573 LLVM_FALLTHROUGH;
545 case R_ARM_THM_JUMP24: {574 case R_ARM_THM_JUMP24: {
546 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0575 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
547 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)576 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
548 // FIXME: I1 and I2 require v6T2ops
549 uint16_t Hi = read16le(Buf);577 uint16_t Hi = read16le(Buf);
550 uint16_t Lo = read16le(Buf + 2);578 uint16_t Lo = read16le(Buf + 2);
551 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S579 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
deps/lld/ELF/Arch/AVR.cpp+3
...@@ -43,12 +43,15 @@ using namespace lld::elf;...@@ -43,12 +43,15 @@ using namespace lld::elf;
43namespace {43namespace {
44class AVR final : public TargetInfo {44class AVR final : public TargetInfo {
45public:45public:
46 AVR();
46 RelExpr getRelExpr(RelType Type, const Symbol &S,47 RelExpr getRelExpr(RelType Type, const Symbol &S,
47 const uint8_t *Loc) const override;48 const uint8_t *Loc) const override;
48 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;49 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
49};50};
50} // namespace51} // namespace
5152
53AVR::AVR() { NoneRel = R_AVR_NONE; }
54
52RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,55RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,
53 const uint8_t *Loc) const {56 const uint8_t *Loc) const {
54 return R_ABS;57 return R_ABS;
deps/lld/ELF/Arch/Hexagon.cpp+192-3
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
99
10#include "InputFiles.h"10#include "InputFiles.h"
11#include "Symbols.h"11#include "Symbols.h"
12#include "SyntheticSections.h"
12#include "Target.h"13#include "Target.h"
13#include "lld/Common/ErrorHandler.h"14#include "lld/Common/ErrorHandler.h"
14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/BinaryFormat/ELF.h"
...@@ -25,15 +26,48 @@ using namespace lld::elf;...@@ -25,15 +26,48 @@ using namespace lld::elf;
25namespace {26namespace {
26class Hexagon final : public TargetInfo {27class Hexagon final : public TargetInfo {
27public:28public:
29 Hexagon();
28 uint32_t calcEFlags() const override;30 uint32_t calcEFlags() const override;
29 RelExpr getRelExpr(RelType Type, const Symbol &S,31 RelExpr getRelExpr(RelType Type, const Symbol &S,
30 const uint8_t *Loc) const override;32 const uint8_t *Loc) const override;
31 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;33 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
34 void writePltHeader(uint8_t *Buf) const override;
35 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
36 int32_t Index, unsigned RelOff) const override;
32};37};
33} // namespace38} // namespace
3439
35// Support V60 only at the moment.40Hexagon::Hexagon() {
36uint32_t Hexagon::calcEFlags() const { return 0x60; }41 PltRel = R_HEX_JMP_SLOT;
42 RelativeRel = R_HEX_RELATIVE;
43 GotRel = R_HEX_GLOB_DAT;
44 GotEntrySize = 4;
45 // The zero'th GOT entry is reserved for the address of _DYNAMIC. The
46 // next 3 are reserved for the dynamic loader.
47 GotPltHeaderEntriesNum = 4;
48 GotPltEntrySize = 4;
49
50 PltEntrySize = 16;
51 PltHeaderSize = 32;
52
53 // Hexagon Linux uses 64K pages by default.
54 DefaultMaxPageSize = 0x10000;
55 NoneRel = R_HEX_NONE;
56}
57
58uint32_t Hexagon::calcEFlags() const {
59 assert(!ObjectFiles.empty());
60
61 // The architecture revision must always be equal to or greater than
62 // greatest revision in the list of inputs.
63 uint32_t Ret = 0;
64 for (InputFile *F : ObjectFiles) {
65 uint32_t EFlags = cast<ObjFile<ELF32LE>>(F)->getObj().getHeader()->e_flags;
66 if (EFlags > Ret)
67 Ret = EFlags;
68 }
69 return Ret;
70}
3771
38static uint32_t applyMask(uint32_t Mask, uint32_t Data) {72static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
39 uint32_t Result = 0;73 uint32_t Result = 0;
...@@ -53,29 +87,143 @@ static uint32_t applyMask(uint32_t Mask, uint32_t Data) {...@@ -53,29 +87,143 @@ static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
53RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,87RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
54 const uint8_t *Loc) const {88 const uint8_t *Loc) const {
55 switch (Type) {89 switch (Type) {
90 case R_HEX_B9_PCREL:
91 case R_HEX_B9_PCREL_X:
92 case R_HEX_B13_PCREL:
56 case R_HEX_B15_PCREL:93 case R_HEX_B15_PCREL:
57 case R_HEX_B15_PCREL_X:94 case R_HEX_B15_PCREL_X:
95 case R_HEX_6_PCREL_X:
96 case R_HEX_32_PCREL:
97 return R_PC;
58 case R_HEX_B22_PCREL:98 case R_HEX_B22_PCREL:
99 case R_HEX_PLT_B22_PCREL:
59 case R_HEX_B22_PCREL_X:100 case R_HEX_B22_PCREL_X:
60 case R_HEX_B32_PCREL_X:101 case R_HEX_B32_PCREL_X:
61 return R_PC;102 return R_PLT_PC;
103 case R_HEX_GOT_11_X:
104 case R_HEX_GOT_16_X:
105 case R_HEX_GOT_32_6_X:
106 return R_HEXAGON_GOT;
62 default:107 default:
63 return R_ABS;108 return R_ABS;
64 }109 }
65}110}
66111
112static uint32_t findMaskR6(uint32_t Insn) {
113 // There are (arguably too) many relocation masks for the DSP's
114 // R_HEX_6_X type. The table below is used to select the correct mask
115 // for the given instruction.
116 struct InstructionMask {
117 uint32_t CmpMask;
118 uint32_t RelocMask;
119 };
120
121 static const InstructionMask R6[] = {
122 {0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
123 {0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
124 {0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
125 {0x42000000, 0x000020f8}, {0x43000000, 0x000007e0},
126 {0x44000000, 0x000020f8}, {0x45000000, 0x000007e0},
127 {0x46000000, 0x000020f8}, {0x47000000, 0x000007e0},
128 {0x6a000000, 0x00001f80}, {0x7c000000, 0x001f2000},
129 {0x9a000000, 0x00000f60}, {0x9b000000, 0x00000f60},
130 {0x9c000000, 0x00000f60}, {0x9d000000, 0x00000f60},
131 {0x9f000000, 0x001f0100}, {0xab000000, 0x0000003f},
132 {0xad000000, 0x0000003f}, {0xaf000000, 0x00030078},
133 {0xd7000000, 0x006020e0}, {0xd8000000, 0x006020e0},
134 {0xdb000000, 0x006020e0}, {0xdf000000, 0x006020e0}};
135
136 // Duplex forms have a fixed mask and parse bits 15:14 are always
137 // zero. Non-duplex insns will always have at least one bit set in the
138 // parse field.
139 if ((0xC000 & Insn) == 0x0)
140 return 0x03f00000;
141
142 for (InstructionMask I : R6)
143 if ((0xff000000 & Insn) == I.CmpMask)
144 return I.RelocMask;
145
146 error("unrecognized instruction for R_HEX_6 relocation: 0x" +
147 utohexstr(Insn));
148 return 0;
149}
150
151static uint32_t findMaskR8(uint32_t Insn) {
152 if ((0xff000000 & Insn) == 0xde000000)
153 return 0x00e020e8;
154 if ((0xff000000 & Insn) == 0x3c000000)
155 return 0x0000207f;
156 return 0x00001fe0;
157}
158
159static uint32_t findMaskR11(uint32_t Insn) {
160 if ((0xff000000 & Insn) == 0xa1000000)
161 return 0x060020ff;
162 return 0x06003fe0;
163}
164
165static uint32_t findMaskR16(uint32_t Insn) {
166 if ((0xff000000 & Insn) == 0x48000000)
167 return 0x061f20ff;
168 if ((0xff000000 & Insn) == 0x49000000)
169 return 0x061f3fe0;
170 if ((0xff000000 & Insn) == 0x78000000)
171 return 0x00df3fe0;
172 if ((0xff000000 & Insn) == 0xb0000000)
173 return 0x0fe03fe0;
174
175 error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
176 utohexstr(Insn));
177 return 0;
178}
179
67static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }180static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
68181
69void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {182void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
70 switch (Type) {183 switch (Type) {
71 case R_HEX_NONE:184 case R_HEX_NONE:
72 break;185 break;
186 case R_HEX_6_PCREL_X:
187 case R_HEX_6_X:
188 or32le(Loc, applyMask(findMaskR6(read32le(Loc)), Val));
189 break;
190 case R_HEX_8_X:
191 or32le(Loc, applyMask(findMaskR8(read32le(Loc)), Val));
192 break;
193 case R_HEX_9_X:
194 or32le(Loc, applyMask(0x00003fe0, Val & 0x3f));
195 break;
196 case R_HEX_10_X:
197 or32le(Loc, applyMask(0x00203fe0, Val & 0x3f));
198 break;
199 case R_HEX_11_X:
200 case R_HEX_GOT_11_X:
201 or32le(Loc, applyMask(findMaskR11(read32le(Loc)), Val & 0x3f));
202 break;
73 case R_HEX_12_X:203 case R_HEX_12_X:
74 or32le(Loc, applyMask(0x000007e0, Val));204 or32le(Loc, applyMask(0x000007e0, Val));
75 break;205 break;
206 case R_HEX_16_X: // These relocs only have 6 effective bits.
207 case R_HEX_GOT_16_X:
208 or32le(Loc, applyMask(findMaskR16(read32le(Loc)), Val & 0x3f));
209 break;
210 case R_HEX_32:
211 case R_HEX_32_PCREL:
212 or32le(Loc, Val);
213 break;
76 case R_HEX_32_6_X:214 case R_HEX_32_6_X:
215 case R_HEX_GOT_32_6_X:
77 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));216 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
78 break;217 break;
218 case R_HEX_B9_PCREL:
219 or32le(Loc, applyMask(0x003000fe, Val >> 2));
220 break;
221 case R_HEX_B9_PCREL_X:
222 or32le(Loc, applyMask(0x003000fe, Val & 0x3f));
223 break;
224 case R_HEX_B13_PCREL:
225 or32le(Loc, applyMask(0x00202ffe, Val >> 2));
226 break;
79 case R_HEX_B15_PCREL:227 case R_HEX_B15_PCREL:
80 or32le(Loc, applyMask(0x00df20fe, Val >> 2));228 or32le(Loc, applyMask(0x00df20fe, Val >> 2));
81 break;229 break;
...@@ -83,6 +231,7 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -83,6 +231,7 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
83 or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));231 or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));
84 break;232 break;
85 case R_HEX_B22_PCREL:233 case R_HEX_B22_PCREL:
234 case R_HEX_PLT_B22_PCREL:
86 or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));235 or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
87 break;236 break;
88 case R_HEX_B22_PCREL_X:237 case R_HEX_B22_PCREL_X:
...@@ -91,12 +240,52 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -91,12 +240,52 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
91 case R_HEX_B32_PCREL_X:240 case R_HEX_B32_PCREL_X:
92 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));241 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
93 break;242 break;
243 case R_HEX_HI16:
244 or32le(Loc, applyMask(0x00c03fff, Val >> 16));
245 break;
246 case R_HEX_LO16:
247 or32le(Loc, applyMask(0x00c03fff, Val));
248 break;
94 default:249 default:
95 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));250 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
96 break;251 break;
97 }252 }
98}253}
99254
255void Hexagon::writePltHeader(uint8_t *Buf) const {
256 const uint8_t PltData[] = {
257 0x00, 0x40, 0x00, 0x00, // { immext (#0)
258 0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0@PCREL) } # @GOT0
259 0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn
260 0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
261 0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
262 0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
263 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
264 0x0c, 0xdb, 0x00, 0x54, // trap0(#0xdb) # bring plt0 into 16byte alignment
265 };
266 memcpy(Buf, PltData, sizeof(PltData));
267
268 // Offset from PLT0 to the GOT.
269 uint64_t Off = In.GotPlt->getVA() - In.Plt->getVA();
270 relocateOne(Buf, R_HEX_B32_PCREL_X, Off);
271 relocateOne(Buf + 4, R_HEX_6_PCREL_X, Off);
272}
273
274void Hexagon::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
275 uint64_t PltEntryAddr, int32_t Index,
276 unsigned RelOff) const {
277 const uint8_t Inst[] = {
278 0x00, 0x40, 0x00, 0x00, // { immext (#0)
279 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) }
280 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)
281 0x00, 0xc0, 0x9c, 0x52, // jumpr r28
282 };
283 memcpy(Buf, Inst, sizeof(Inst));
284
285 relocateOne(Buf, R_HEX_B32_PCREL_X, GotPltEntryAddr - PltEntryAddr);
286 relocateOne(Buf + 4, R_HEX_6_PCREL_X, GotPltEntryAddr - PltEntryAddr);
287}
288
100TargetInfo *elf::getHexagonTargetInfo() {289TargetInfo *elf::getHexagonTargetInfo() {
101 static Hexagon Target;290 static Hexagon Target;
102 return &Target;291 return &Target;
deps/lld/ELF/Arch/MSP430.cpp created+94
...@@ -0,0 +1,94 @@
1//===- MSP430.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The MSP430 is a 16-bit microcontroller RISC architecture. The instruction set
11// has only 27 core instructions orthogonally augmented with a variety
12// of addressing modes for source and destination operands. Entire address space
13// of MSP430 is 64KB (the extended MSP430X architecture is not considered here).
14// A typical MSP430 MCU has several kilobytes of RAM and ROM, plenty
15// of peripherals and is generally optimized for a low power consumption.
16//
17//===----------------------------------------------------------------------===//
18
19#include "InputFiles.h"
20#include "Symbols.h"
21#include "Target.h"
22#include "lld/Common/ErrorHandler.h"
23#include "llvm/Object/ELF.h"
24#include "llvm/Support/Endian.h"
25
26using namespace llvm;
27using namespace llvm::object;
28using namespace llvm::support::endian;
29using namespace llvm::ELF;
30using namespace lld;
31using namespace lld::elf;
32
33namespace {
34class MSP430 final : public TargetInfo {
35public:
36 MSP430();
37 RelExpr getRelExpr(RelType Type, const Symbol &S,
38 const uint8_t *Loc) const override;
39 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
40};
41} // namespace
42
43MSP430::MSP430() {
44 // mov.b #0, r3
45 TrapInstr = {0x43, 0x43, 0x43, 0x43};
46}
47
48RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
49 const uint8_t *Loc) const {
50 switch (Type) {
51 case R_MSP430_10_PCREL:
52 case R_MSP430_16_PCREL:
53 case R_MSP430_16_PCREL_BYTE:
54 case R_MSP430_2X_PCREL:
55 case R_MSP430_RL_PCREL:
56 case R_MSP430_SYM_DIFF:
57 return R_PC;
58 default:
59 return R_ABS;
60 }
61}
62
63void MSP430::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
64 switch (Type) {
65 case R_MSP430_8:
66 checkIntUInt(Loc, Val, 8, Type);
67 *Loc = Val;
68 break;
69 case R_MSP430_16:
70 case R_MSP430_16_PCREL:
71 case R_MSP430_16_BYTE:
72 case R_MSP430_16_PCREL_BYTE:
73 checkIntUInt(Loc, Val, 16, Type);
74 write16le(Loc, Val);
75 break;
76 case R_MSP430_32:
77 checkIntUInt(Loc, Val, 32, Type);
78 write32le(Loc, Val);
79 break;
80 case R_MSP430_10_PCREL: {
81 int16_t Offset = ((int16_t)Val >> 1) - 1;
82 checkInt(Loc, Offset, 10, Type);
83 write16le(Loc, (read16le(Loc) & 0xFC00) | (Offset & 0x3FF));
84 break;
85 }
86 default:
87 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
88 }
89}
90
91TargetInfo *elf::getMSP430TargetInfo() {
92 static MSP430 Target;
93 return &Target;
94}
deps/lld/ELF/Arch/Mips.cpp+8-5
...@@ -53,9 +53,12 @@ template <class ELFT> MIPS<ELFT>::MIPS() {...@@ -53,9 +53,12 @@ template <class ELFT> MIPS<ELFT>::MIPS() {
53 PltEntrySize = 16;53 PltEntrySize = 16;
54 PltHeaderSize = 32;54 PltHeaderSize = 32;
55 CopyRel = R_MIPS_COPY;55 CopyRel = R_MIPS_COPY;
56 NoneRel = R_MIPS_NONE;
56 PltRel = R_MIPS_JUMP_SLOT;57 PltRel = R_MIPS_JUMP_SLOT;
57 NeedsThunks = true;58 NeedsThunks = true;
58 TrapInstr = 0xefefefef;59
60 // Set `sigrie 1` as a trap instruction.
61 write32(TrapInstr.data(), 0x04170001);
5962
60 if (ELFT::Is64Bits) {63 if (ELFT::Is64Bits) {
61 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;64 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
...@@ -185,7 +188,7 @@ template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {...@@ -185,7 +188,7 @@ template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
185188
186template <class ELFT>189template <class ELFT>
187void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {190void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
188 uint64_t VA = InX::Plt->getVA();191 uint64_t VA = In.Plt->getVA();
189 if (isMicroMips())192 if (isMicroMips())
190 VA |= 1;193 VA |= 1;
191 write32<ELFT::TargetEndianness>(Buf, VA);194 write32<ELFT::TargetEndianness>(Buf, VA);
...@@ -239,8 +242,8 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,...@@ -239,8 +242,8 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
239template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {242template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
240 const endianness E = ELFT::TargetEndianness;243 const endianness E = ELFT::TargetEndianness;
241 if (isMicroMips()) {244 if (isMicroMips()) {
242 uint64_t GotPlt = InX::GotPlt->getVA();245 uint64_t GotPlt = In.GotPlt->getVA();
243 uint64_t Plt = InX::Plt->getVA();246 uint64_t Plt = In.Plt->getVA();
244 // Overwrite trap instructions written by Writer::writeTrapInstr.247 // Overwrite trap instructions written by Writer::writeTrapInstr.
245 memset(Buf, 0, PltHeaderSize);248 memset(Buf, 0, PltHeaderSize);
246249
...@@ -292,7 +295,7 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {...@@ -292,7 +295,7 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
292 write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25295 write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
293 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2296 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
294297
295 uint64_t GotPlt = InX::GotPlt->getVA();298 uint64_t GotPlt = In.GotPlt->getVA();
296 writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);299 writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
297 writeValue<E>(Buf + 4, GotPlt, 16, 0);300 writeValue<E>(Buf + 4, GotPlt, 16, 0);
298 writeValue<E>(Buf + 8, GotPlt, 16, 0);301 writeValue<E>(Buf + 8, GotPlt, 16, 0);
deps/lld/ELF/Arch/PPC.cpp+5
...@@ -29,6 +29,7 @@ public:...@@ -29,6 +29,7 @@ public:
29} // namespace29} // namespace
3030
31PPC::PPC() {31PPC::PPC() {
32 NoneRel = R_PPC_NONE;
32 GotBaseSymOff = 0x8000;33 GotBaseSymOff = 0x8000;
33 GotBaseSymInGotPlt = false;34 GotBaseSymInGotPlt = false;
34}35}
...@@ -36,6 +37,7 @@ PPC::PPC() {...@@ -36,6 +37,7 @@ PPC::PPC() {
36RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,37RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
37 const uint8_t *Loc) const {38 const uint8_t *Loc) const {
38 switch (Type) {39 switch (Type) {
40 case R_PPC_REL14:
39 case R_PPC_REL24:41 case R_PPC_REL24:
40 case R_PPC_REL32:42 case R_PPC_REL32:
41 return R_PC;43 return R_PC;
...@@ -61,6 +63,9 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -61,6 +63,9 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
61 case R_PPC_REL32:63 case R_PPC_REL32:
62 write32be(Loc, Val);64 write32be(Loc, Val);
63 break;65 break;
66 case R_PPC_REL14:
67 write32be(Loc, read32be(Loc) | (Val & 0xFFFC));
68 break;
64 case R_PPC_PLTREL24:69 case R_PPC_PLTREL24:
65 case R_PPC_REL24:70 case R_PPC_REL24:
66 write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));71 write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));
deps/lld/ELF/Arch/PPC64.cpp+436-37
...@@ -23,12 +23,49 @@ using namespace lld::elf;...@@ -23,12 +23,49 @@ using namespace lld::elf;
23static uint64_t PPC64TocOffset = 0x8000;23static uint64_t PPC64TocOffset = 0x8000;
24static uint64_t DynamicThreadPointerOffset = 0x8000;24static uint64_t DynamicThreadPointerOffset = 0x8000;
2525
26// The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
27// instructions that can be used as part of the initial exec TLS sequence.
28enum XFormOpcd {
29 LBZX = 87,
30 LHZX = 279,
31 LWZX = 23,
32 LDX = 21,
33 STBX = 215,
34 STHX = 407,
35 STWX = 151,
36 STDX = 149,
37 ADD = 266,
38};
39
40enum DFormOpcd {
41 LBZ = 34,
42 LBZU = 35,
43 LHZ = 40,
44 LHZU = 41,
45 LHAU = 43,
46 LWZ = 32,
47 LWZU = 33,
48 LFSU = 49,
49 LD = 58,
50 LFDU = 51,
51 STB = 38,
52 STBU = 39,
53 STH = 44,
54 STHU = 45,
55 STW = 36,
56 STWU = 37,
57 STFSU = 53,
58 STFDU = 55,
59 STD = 62,
60 ADDI = 14
61};
62
26uint64_t elf::getPPC64TocBase() {63uint64_t elf::getPPC64TocBase() {
27 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The64 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
28 // TOC starts where the first of these sections starts. We always create a65 // TOC starts where the first of these sections starts. We always create a
29 // .got when we see a relocation that uses it, so for us the start is always66 // .got when we see a relocation that uses it, so for us the start is always
30 // the .got.67 // the .got.
31 uint64_t TocVA = InX::Got->getVA();68 uint64_t TocVA = In.Got->getVA();
3269
33 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x800070 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
34 // thus permitting a full 64 Kbytes segment. Note that the glibc startup71 // thus permitting a full 64 Kbytes segment. Note that the glibc startup
...@@ -37,6 +74,31 @@ uint64_t elf::getPPC64TocBase() {...@@ -37,6 +74,31 @@ uint64_t elf::getPPC64TocBase() {
37 return TocVA + PPC64TocOffset;74 return TocVA + PPC64TocOffset;
38}75}
3976
77unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
78 // The offset is encoded into the 3 most significant bits of the st_other
79 // field, with some special values described in section 3.4.1 of the ABI:
80 // 0 --> Zero offset between the GEP and LEP, and the function does NOT use
81 // the TOC pointer (r2). r2 will hold the same value on returning from
82 // the function as it did on entering the function.
83 // 1 --> Zero offset between the GEP and LEP, and r2 should be treated as a
84 // caller-saved register for all callers.
85 // 2-6 --> The binary logarithm of the offset eg:
86 // 2 --> 2^2 = 4 bytes --> 1 instruction.
87 // 6 --> 2^6 = 64 bytes --> 16 instructions.
88 // 7 --> Reserved.
89 uint8_t GepToLep = (StOther >> 5) & 7;
90 if (GepToLep < 2)
91 return 0;
92
93 // The value encoded in the st_other bits is the
94 // log-base-2(offset).
95 if (GepToLep < 7)
96 return 1 << GepToLep;
97
98 error("reserved value of 7 in the 3 most-significant-bits of st_other");
99 return 0;
100}
101
40namespace {102namespace {
41class PPC64 final : public TargetInfo {103class PPC64 final : public TargetInfo {
42public:104public:
...@@ -51,11 +113,16 @@ public:...@@ -51,11 +113,16 @@ public:
51 void writeGotHeader(uint8_t *Buf) const override;113 void writeGotHeader(uint8_t *Buf) const override;
52 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,114 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
53 uint64_t BranchAddr, const Symbol &S) const override;115 uint64_t BranchAddr, const Symbol &S) const override;
116 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
54 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,117 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
55 RelExpr Expr) const override;118 RelExpr Expr) const override;
56 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;119 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
57 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;120 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
58 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;121 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
122 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
123
124 bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
125 uint8_t StOther) const override;
59};126};
60} // namespace127} // namespace
61128
...@@ -71,8 +138,64 @@ static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; }...@@ -71,8 +138,64 @@ static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; }
71static uint16_t highest(uint64_t V) { return V >> 48; }138static uint16_t highest(uint64_t V) { return V >> 48; }
72static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; }139static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; }
73140
141// Extracts the 'PO' field of an instruction encoding.
142static uint8_t getPrimaryOpCode(uint32_t Encoding) { return (Encoding >> 26); }
143
144static bool isDQFormInstruction(uint32_t Encoding) {
145 switch (getPrimaryOpCode(Encoding)) {
146 default:
147 return false;
148 case 56:
149 // The only instruction with a primary opcode of 56 is `lq`.
150 return true;
151 case 61:
152 // There are both DS and DQ instruction forms with this primary opcode.
153 // Namely `lxv` and `stxv` are the DQ-forms that use it.
154 // The DS 'XO' bits being set to 01 is restricted to DQ form.
155 return (Encoding & 3) == 0x1;
156 }
157}
158
159static bool isInstructionUpdateForm(uint32_t Encoding) {
160 switch (getPrimaryOpCode(Encoding)) {
161 default:
162 return false;
163 case LBZU:
164 case LHAU:
165 case LHZU:
166 case LWZU:
167 case LFSU:
168 case LFDU:
169 case STBU:
170 case STHU:
171 case STWU:
172 case STFSU:
173 case STFDU:
174 return true;
175 // LWA has the same opcode as LD, and the DS bits is what differentiates
176 // between LD/LDU/LWA
177 case LD:
178 case STD:
179 return (Encoding & 3) == 1;
180 }
181}
182
183// There are a number of places when we either want to read or write an
184// instruction when handling a half16 relocation type. On big-endian the buffer
185// pointer is pointing into the middle of the word we want to extract, and on
186// little-endian it is pointing to the start of the word. These 2 helpers are to
187// simplify reading and writing in that context.
188static void writeInstrFromHalf16(uint8_t *Loc, uint32_t Instr) {
189 write32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0), Instr);
190}
191
192static uint32_t readInstrFromHalf16(const uint8_t *Loc) {
193 return read32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0));
194}
195
74PPC64::PPC64() {196PPC64::PPC64() {
75 GotRel = R_PPC64_GLOB_DAT;197 GotRel = R_PPC64_GLOB_DAT;
198 NoneRel = R_PPC64_NONE;
76 PltRel = R_PPC64_JMP_SLOT;199 PltRel = R_PPC64_JMP_SLOT;
77 RelativeRel = R_PPC64_RELATIVE;200 RelativeRel = R_PPC64_RELATIVE;
78 IRelativeRel = R_PPC64_IRELATIVE;201 IRelativeRel = R_PPC64_IRELATIVE;
...@@ -85,14 +208,14 @@ PPC64::PPC64() {...@@ -85,14 +208,14 @@ PPC64::PPC64() {
85 GotPltHeaderEntriesNum = 2;208 GotPltHeaderEntriesNum = 2;
86 PltHeaderSize = 60;209 PltHeaderSize = 60;
87 NeedsThunks = true;210 NeedsThunks = true;
88 TcbSize = 8;
89 TlsTpOffset = 0x7000;
90211
91 TlsModuleIndexRel = R_PPC64_DTPMOD64;212 TlsModuleIndexRel = R_PPC64_DTPMOD64;
92 TlsOffsetRel = R_PPC64_DTPREL64;213 TlsOffsetRel = R_PPC64_DTPREL64;
93214
94 TlsGotRel = R_PPC64_TPREL64;215 TlsGotRel = R_PPC64_TPREL64;
95216
217 NeedsMoreStackNonSplit = false;
218
96 // We need 64K pages (at least under glibc/Linux, the loader won't219 // We need 64K pages (at least under glibc/Linux, the loader won't
97 // set different permissions on a finer granularity than that).220 // set different permissions on a finer granularity than that).
98 DefaultMaxPageSize = 65536;221 DefaultMaxPageSize = 65536;
...@@ -107,8 +230,7 @@ PPC64::PPC64() {...@@ -107,8 +230,7 @@ PPC64::PPC64() {
107 // use 0x10000000 as the starting address.230 // use 0x10000000 as the starting address.
108 DefaultImageBase = 0x10000000;231 DefaultImageBase = 0x10000000;
109232
110 TrapInstr =233 write32(TrapInstr.data(), 0x7fe00008);
111 (Config->IsLE == sys::IsLittleEndianHost) ? 0x7fe00008 : 0x0800e07f;
112}234}
113235
114static uint32_t getEFlags(InputFile *File) {236static uint32_t getEFlags(InputFile *File) {
...@@ -146,27 +268,29 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -146,27 +268,29 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
146 // bl __tls_get_addr(x@tlsgd) into nop268 // bl __tls_get_addr(x@tlsgd) into nop
147 // nop into addi r3, r3, x@tprel@l269 // nop into addi r3, r3, x@tprel@l
148270
149 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
150
151 switch (Type) {271 switch (Type) {
152 case R_PPC64_GOT_TLSGD16_HA:272 case R_PPC64_GOT_TLSGD16_HA:
153 write32(Loc - EndianOffset, 0x60000000); // nop273 writeInstrFromHalf16(Loc, 0x60000000); // nop
154 break;274 break;
275 case R_PPC64_GOT_TLSGD16:
155 case R_PPC64_GOT_TLSGD16_LO:276 case R_PPC64_GOT_TLSGD16_LO:
156 write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13277 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
157 relocateOne(Loc, R_PPC64_TPREL16_HA, Val);278 relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
158 break;279 break;
159 case R_PPC64_TLSGD:280 case R_PPC64_TLSGD:
160 write32(Loc, 0x60000000); // nop281 write32(Loc, 0x60000000); // nop
161 write32(Loc + 4, 0x38630000); // addi r3, r3282 write32(Loc + 4, 0x38630000); // addi r3, r3
162 relocateOne(Loc + 4 + EndianOffset, R_PPC64_TPREL16_LO, Val);283 // Since we are relocating a half16 type relocation and Loc + 4 points to
284 // the start of an instruction we need to advance the buffer by an extra
285 // 2 bytes on BE.
286 relocateOne(Loc + 4 + (Config->EKind == ELF64BEKind ? 2 : 0),
287 R_PPC64_TPREL16_LO, Val);
163 break;288 break;
164 default:289 default:
165 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");290 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
166 }291 }
167}292}
168293
169
170void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {294void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
171 // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.295 // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
172 // The local dynamic code sequence for a global `x` will look like:296 // The local dynamic code sequence for a global `x` will look like:
...@@ -183,13 +307,12 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -183,13 +307,12 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
183 // bl __tls_get_addr(x@tlsgd) into nop307 // bl __tls_get_addr(x@tlsgd) into nop
184 // nop into addi r3, r3, 4096308 // nop into addi r3, r3, 4096
185309
186 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
187 switch (Type) {310 switch (Type) {
188 case R_PPC64_GOT_TLSLD16_HA:311 case R_PPC64_GOT_TLSLD16_HA:
189 write32(Loc - EndianOffset, 0x60000000); // nop312 writeInstrFromHalf16(Loc, 0x60000000); // nop
190 break;313 break;
191 case R_PPC64_GOT_TLSLD16_LO:314 case R_PPC64_GOT_TLSLD16_LO:
192 write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13, 0315 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
193 break;316 break;
194 case R_PPC64_TLSLD:317 case R_PPC64_TLSLD:
195 write32(Loc, 0x60000000); // nop318 write32(Loc, 0x60000000); // nop
...@@ -212,9 +335,90 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -212,9 +335,90 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
212 }335 }
213}336}
214337
338static unsigned getDFormOp(unsigned SecondaryOp) {
339 switch (SecondaryOp) {
340 case LBZX:
341 return LBZ;
342 case LHZX:
343 return LHZ;
344 case LWZX:
345 return LWZ;
346 case LDX:
347 return LD;
348 case STBX:
349 return STB;
350 case STHX:
351 return STH;
352 case STWX:
353 return STW;
354 case STDX:
355 return STD;
356 case ADD:
357 return ADDI;
358 default:
359 error("unrecognized instruction for IE to LE R_PPC64_TLS");
360 return 0;
361 }
362}
363
364void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
365 // The initial exec code sequence for a global `x` will look like:
366 // Instruction Relocation Symbol
367 // addis r9, r2, x@got@tprel@ha R_PPC64_GOT_TPREL16_HA x
368 // ld r9, x@got@tprel@l(r9) R_PPC64_GOT_TPREL16_LO_DS x
369 // add r9, r9, x@tls R_PPC64_TLS x
370
371 // Relaxing to local exec entails converting:
372 // addis r9, r2, x@got@tprel@ha into nop
373 // ld r9, x@got@tprel@l(r9) into addis r9, r13, x@tprel@ha
374 // add r9, r9, x@tls into addi r9, r9, x@tprel@l
375
376 // x@tls R_PPC64_TLS is a relocation which does not compute anything,
377 // it is replaced with r13 (thread pointer).
378
379 // The add instruction in the initial exec sequence has multiple variations
380 // that need to be handled. If we are building an address it will use an add
381 // instruction, if we are accessing memory it will use any of the X-form
382 // indexed load or store instructions.
383
384 unsigned Offset = (Config->EKind == ELF64BEKind) ? 2 : 0;
385 switch (Type) {
386 case R_PPC64_GOT_TPREL16_HA:
387 write32(Loc - Offset, 0x60000000); // nop
388 break;
389 case R_PPC64_GOT_TPREL16_LO_DS:
390 case R_PPC64_GOT_TPREL16_DS: {
391 uint32_t RegNo = read32(Loc - Offset) & 0x03E00000; // bits 6-10
392 write32(Loc - Offset, 0x3C0D0000 | RegNo); // addis RegNo, r13
393 relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
394 break;
395 }
396 case R_PPC64_TLS: {
397 uint32_t PrimaryOp = getPrimaryOpCode(read32(Loc));
398 if (PrimaryOp != 31)
399 error("unrecognized instruction for IE to LE R_PPC64_TLS");
400 uint32_t SecondaryOp = (read32(Loc) & 0x000007FE) >> 1; // bits 21-30
401 uint32_t DFormOp = getDFormOp(SecondaryOp);
402 write32(Loc, ((DFormOp << 26) | (read32(Loc) & 0x03FFFFFF)));
403 relocateOne(Loc + Offset, R_PPC64_TPREL16_LO, Val);
404 break;
405 }
406 default:
407 llvm_unreachable("unknown relocation for IE to LE");
408 break;
409 }
410}
411
215RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,412RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
216 const uint8_t *Loc) const {413 const uint8_t *Loc) const {
217 switch (Type) {414 switch (Type) {
415 case R_PPC64_GOT16:
416 case R_PPC64_GOT16_DS:
417 case R_PPC64_GOT16_HA:
418 case R_PPC64_GOT16_HI:
419 case R_PPC64_GOT16_LO:
420 case R_PPC64_GOT16_LO_DS:
421 return R_GOT_OFF;
218 case R_PPC64_TOC16:422 case R_PPC64_TOC16:
219 case R_PPC64_TOC16_DS:423 case R_PPC64_TOC16_DS:
220 case R_PPC64_TOC16_HA:424 case R_PPC64_TOC16_HA:
...@@ -224,6 +428,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,...@@ -224,6 +428,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
224 return R_GOTREL;428 return R_GOTREL;
225 case R_PPC64_TOC:429 case R_PPC64_TOC:
226 return R_PPC_TOC;430 return R_PPC_TOC;
431 case R_PPC64_REL14:
227 case R_PPC64_REL24:432 case R_PPC64_REL24:
228 return R_PPC_CALL_PLT;433 return R_PPC_CALL_PLT;
229 case R_PPC64_REL16_LO:434 case R_PPC64_REL16_LO:
...@@ -279,7 +484,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,...@@ -279,7 +484,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
279 case R_PPC64_TLSLD:484 case R_PPC64_TLSLD:
280 return R_TLSLD_HINT;485 return R_TLSLD_HINT;
281 case R_PPC64_TLS:486 case R_PPC64_TLS:
282 return R_HINT;487 return R_TLSIE_HINT;
283 default:488 default:
284 return R_ABS;489 return R_ABS;
285 }490 }
...@@ -308,16 +513,16 @@ void PPC64::writePltHeader(uint8_t *Buf) const {...@@ -308,16 +513,16 @@ void PPC64::writePltHeader(uint8_t *Buf) const {
308 // The 'bcl' instruction will set the link register to the address of the513 // The 'bcl' instruction will set the link register to the address of the
309 // following instruction ('mflr r11'). Here we store the offset from that514 // following instruction ('mflr r11'). Here we store the offset from that
310 // instruction to the first entry in the GotPlt section.515 // instruction to the first entry in the GotPlt section.
311 int64_t GotPltOffset = InX::GotPlt->getVA() - (InX::Plt->getVA() + 8);516 int64_t GotPltOffset = In.GotPlt->getVA() - (In.Plt->getVA() + 8);
312 write64(Buf + 52, GotPltOffset);517 write64(Buf + 52, GotPltOffset);
313}518}
314519
315void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,520void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
316 uint64_t PltEntryAddr, int32_t Index,521 uint64_t PltEntryAddr, int32_t Index,
317 unsigned RelOff) const {522 unsigned RelOff) const {
318 int32_t Offset = PltHeaderSize + Index * PltEntrySize;523 int32_t Offset = PltHeaderSize + Index * PltEntrySize;
319 // bl __glink_PLTresolve524 // bl __glink_PLTresolve
320 write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));525 write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
321}526}
322527
323static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {528static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
...@@ -328,30 +533,36 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {...@@ -328,30 +533,36 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
328533
329 switch (Type) {534 switch (Type) {
330 // TOC biased relocation.535 // TOC biased relocation.
536 case R_PPC64_GOT16:
331 case R_PPC64_GOT_TLSGD16:537 case R_PPC64_GOT_TLSGD16:
332 case R_PPC64_GOT_TLSLD16:538 case R_PPC64_GOT_TLSLD16:
333 case R_PPC64_TOC16:539 case R_PPC64_TOC16:
334 return {R_PPC64_ADDR16, TocBiasedVal};540 return {R_PPC64_ADDR16, TocBiasedVal};
541 case R_PPC64_GOT16_DS:
335 case R_PPC64_TOC16_DS:542 case R_PPC64_TOC16_DS:
336 case R_PPC64_GOT_TPREL16_DS:543 case R_PPC64_GOT_TPREL16_DS:
337 case R_PPC64_GOT_DTPREL16_DS:544 case R_PPC64_GOT_DTPREL16_DS:
338 return {R_PPC64_ADDR16_DS, TocBiasedVal};545 return {R_PPC64_ADDR16_DS, TocBiasedVal};
546 case R_PPC64_GOT16_HA:
339 case R_PPC64_GOT_TLSGD16_HA:547 case R_PPC64_GOT_TLSGD16_HA:
340 case R_PPC64_GOT_TLSLD16_HA:548 case R_PPC64_GOT_TLSLD16_HA:
341 case R_PPC64_GOT_TPREL16_HA:549 case R_PPC64_GOT_TPREL16_HA:
342 case R_PPC64_GOT_DTPREL16_HA:550 case R_PPC64_GOT_DTPREL16_HA:
343 case R_PPC64_TOC16_HA:551 case R_PPC64_TOC16_HA:
344 return {R_PPC64_ADDR16_HA, TocBiasedVal};552 return {R_PPC64_ADDR16_HA, TocBiasedVal};
553 case R_PPC64_GOT16_HI:
345 case R_PPC64_GOT_TLSGD16_HI:554 case R_PPC64_GOT_TLSGD16_HI:
346 case R_PPC64_GOT_TLSLD16_HI:555 case R_PPC64_GOT_TLSLD16_HI:
347 case R_PPC64_GOT_TPREL16_HI:556 case R_PPC64_GOT_TPREL16_HI:
348 case R_PPC64_GOT_DTPREL16_HI:557 case R_PPC64_GOT_DTPREL16_HI:
349 case R_PPC64_TOC16_HI:558 case R_PPC64_TOC16_HI:
350 return {R_PPC64_ADDR16_HI, TocBiasedVal};559 return {R_PPC64_ADDR16_HI, TocBiasedVal};
560 case R_PPC64_GOT16_LO:
351 case R_PPC64_GOT_TLSGD16_LO:561 case R_PPC64_GOT_TLSGD16_LO:
352 case R_PPC64_GOT_TLSLD16_LO:562 case R_PPC64_GOT_TLSLD16_LO:
353 case R_PPC64_TOC16_LO:563 case R_PPC64_TOC16_LO:
354 return {R_PPC64_ADDR16_LO, TocBiasedVal};564 return {R_PPC64_ADDR16_LO, TocBiasedVal};
565 case R_PPC64_GOT16_LO_DS:
355 case R_PPC64_TOC16_LO_DS:566 case R_PPC64_TOC16_LO_DS:
356 case R_PPC64_GOT_TPREL16_LO_DS:567 case R_PPC64_GOT_TPREL16_LO_DS:
357 case R_PPC64_GOT_DTPREL16_LO_DS:568 case R_PPC64_GOT_DTPREL16_LO_DS:
...@@ -386,9 +597,27 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {...@@ -386,9 +597,27 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
386 }597 }
387}598}
388599
600static bool isTocOptType(RelType Type) {
601 switch (Type) {
602 case R_PPC64_GOT16_HA:
603 case R_PPC64_GOT16_LO_DS:
604 case R_PPC64_TOC16_HA:
605 case R_PPC64_TOC16_LO_DS:
606 case R_PPC64_TOC16_LO:
607 return true;
608 default:
609 return false;
610 }
611}
612
389void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {613void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
390 // For a TOC-relative relocation, proceed in terms of the corresponding614 // We need to save the original relocation type to use in diagnostics, and
391 // ADDR16 relocation type.615 // use the original type to determine if we should toc-optimize the
616 // instructions being relocated.
617 RelType OriginalType = Type;
618 bool ShouldTocOptimize = isTocOptType(Type);
619 // For dynamic thread pointer relative, toc-relative, and got-indirect
620 // relocations, proceed in terms of the corresponding ADDR16 relocation type.
392 std::tie(Type, Val) = toAddr16Rel(Type, Val);621 std::tie(Type, Val) = toAddr16Rel(Type, Val);
393622
394 switch (Type) {623 switch (Type) {
...@@ -401,18 +630,25 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -401,18 +630,25 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
401 }630 }
402 case R_PPC64_ADDR16:631 case R_PPC64_ADDR16:
403 case R_PPC64_TPREL16:632 case R_PPC64_TPREL16:
404 checkInt(Loc, Val, 16, Type);633 checkInt(Loc, Val, 16, OriginalType);
405 write16(Loc, Val);634 write16(Loc, Val);
406 break;635 break;
407 case R_PPC64_ADDR16_DS:636 case R_PPC64_ADDR16_DS:
408 case R_PPC64_TPREL16_DS:637 case R_PPC64_TPREL16_DS: {
409 checkInt(Loc, Val, 16, Type);638 checkInt(Loc, Val, 16, OriginalType);
410 write16(Loc, (read16(Loc) & 3) | (Val & ~3));639 // DQ-form instructions use bits 28-31 as part of the instruction encoding
411 break;640 // DS-form instructions only use bits 30-31.
641 uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3;
642 checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
643 write16(Loc, (read16(Loc) & Mask) | lo(Val));
644 } break;
412 case R_PPC64_ADDR16_HA:645 case R_PPC64_ADDR16_HA:
413 case R_PPC64_REL16_HA:646 case R_PPC64_REL16_HA:
414 case R_PPC64_TPREL16_HA:647 case R_PPC64_TPREL16_HA:
415 write16(Loc, ha(Val));648 if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
649 writeInstrFromHalf16(Loc, 0x60000000);
650 else
651 write16(Loc, ha(Val));
416 break;652 break;
417 case R_PPC64_ADDR16_HI:653 case R_PPC64_ADDR16_HI:
418 case R_PPC64_REL16_HI:654 case R_PPC64_REL16_HI:
...@@ -438,12 +674,40 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -438,12 +674,40 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
438 case R_PPC64_ADDR16_LO:674 case R_PPC64_ADDR16_LO:
439 case R_PPC64_REL16_LO:675 case R_PPC64_REL16_LO:
440 case R_PPC64_TPREL16_LO:676 case R_PPC64_TPREL16_LO:
677 // When the high-adjusted part of a toc relocation evalutes to 0, it is
678 // changed into a nop. The lo part then needs to be updated to use the
679 // toc-pointer register r2, as the base register.
680 if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
681 uint32_t Instr = readInstrFromHalf16(Loc);
682 if (isInstructionUpdateForm(Instr))
683 error(getErrorLocation(Loc) +
684 "can't toc-optimize an update instruction: 0x" +
685 utohexstr(Instr));
686 Instr = (Instr & 0xFFE00000) | 0x00020000;
687 writeInstrFromHalf16(Loc, Instr);
688 }
441 write16(Loc, lo(Val));689 write16(Loc, lo(Val));
442 break;690 break;
443 case R_PPC64_ADDR16_LO_DS:691 case R_PPC64_ADDR16_LO_DS:
444 case R_PPC64_TPREL16_LO_DS:692 case R_PPC64_TPREL16_LO_DS: {
445 write16(Loc, (read16(Loc) & 3) | (lo(Val) & ~3));693 // DQ-form instructions use bits 28-31 as part of the instruction encoding
446 break;694 // DS-form instructions only use bits 30-31.
695 uint32_t Inst = readInstrFromHalf16(Loc);
696 uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
697 checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
698 if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
699 // When the high-adjusted part of a toc relocation evalutes to 0, it is
700 // changed into a nop. The lo part then needs to be updated to use the toc
701 // pointer register r2, as the base register.
702 if (isInstructionUpdateForm(Inst))
703 error(getErrorLocation(Loc) +
704 "Can't toc-optimize an update instruction: 0x" +
705 Twine::utohexstr(Inst));
706 Inst = (Inst & 0xFFE0000F) | 0x00020000;
707 writeInstrFromHalf16(Loc, Inst);
708 }
709 write16(Loc, (read16(Loc) & Mask) | lo(Val));
710 } break;
447 case R_PPC64_ADDR32:711 case R_PPC64_ADDR32:
448 case R_PPC64_REL32:712 case R_PPC64_REL32:
449 checkInt(Loc, Val, 32, Type);713 checkInt(Loc, Val, 32, Type);
...@@ -454,9 +718,17 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -454,9 +718,17 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
454 case R_PPC64_TOC:718 case R_PPC64_TOC:
455 write64(Loc, Val);719 write64(Loc, Val);
456 break;720 break;
721 case R_PPC64_REL14: {
722 uint32_t Mask = 0x0000FFFC;
723 checkInt(Loc, Val, 16, Type);
724 checkAlignment(Loc, Val, 4, Type);
725 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
726 break;
727 }
457 case R_PPC64_REL24: {728 case R_PPC64_REL24: {
458 uint32_t Mask = 0x03FFFFFC;729 uint32_t Mask = 0x03FFFFFC;
459 checkInt(Loc, Val, 24, Type);730 checkInt(Loc, Val, 26, Type);
731 checkAlignment(Loc, Val, 4, Type);
460 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));732 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
461 break;733 break;
462 }734 }
...@@ -470,9 +742,30 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -470,9 +742,30 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
470742
471bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,743bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
472 uint64_t BranchAddr, const Symbol &S) const {744 uint64_t BranchAddr, const Symbol &S) const {
473 // If a function is in the plt it needs to be called through745 if (Type != R_PPC64_REL14 && Type != R_PPC64_REL24)
474 // a call stub.746 return false;
475 return Type == R_PPC64_REL24 && S.isInPlt();747
748 // If a function is in the Plt it needs to be called with a call-stub.
749 if (S.isInPlt())
750 return true;
751
752 // If a symbol is a weak undefined and we are compiling an executable
753 // it doesn't need a range-extending thunk since it can't be called.
754 if (S.isUndefWeak() && !Config->Shared)
755 return false;
756
757 // If the offset exceeds the range of the branch type then it will need
758 // a range-extending thunk.
759 return !inBranchRange(Type, BranchAddr, S.getVA());
760}
761
762bool PPC64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
763 int64_t Offset = Dst - Src;
764 if (Type == R_PPC64_REL14)
765 return isInt<16>(Offset);
766 if (Type == R_PPC64_REL24)
767 return isInt<26>(Offset);
768 llvm_unreachable("unsupported relocation type used in branch");
476}769}
477770
478RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,771RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
...@@ -511,9 +804,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -511,9 +804,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
511 case R_PPC64_GOT_TLSGD16_LO: {804 case R_PPC64_GOT_TLSGD16_LO: {
512 // Relax from addi r3, rA, sym@got@tlsgd@l to805 // Relax from addi r3, rA, sym@got@tlsgd@l to
513 // ld r3, sym@got@tprel@l(rA)806 // ld r3, sym@got@tprel@l(rA)
514 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;807 uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16));
515 uint32_t InputRegister = (read32(Loc - EndianOffset) & (0x1f << 16));808 writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister);
516 write32(Loc - EndianOffset, 0xE8600000 | InputRegister);
517 relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);809 relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
518 return;810 return;
519 }811 }
...@@ -526,6 +818,113 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {...@@ -526,6 +818,113 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
526 }818 }
527}819}
528820
821// The prologue for a split-stack function is expected to look roughly
822// like this:
823// .Lglobal_entry_point:
824// # TOC pointer initalization.
825// ...
826// .Llocal_entry_point:
827// # load the __private_ss member of the threads tcbhead.
828// ld r0,-0x7000-64(r13)
829// # subtract the functions stack size from the stack pointer.
830// addis r12, r1, ha(-stack-frame size)
831// addi r12, r12, l(-stack-frame size)
832// # compare needed to actual and branch to allocate_more_stack if more
833// # space is needed, otherwise fallthrough to 'normal' function body.
834// cmpld cr7,r12,r0
835// blt- cr7, .Lallocate_more_stack
836//
837// -) The allocate_more_stack block might be placed after the split-stack
838// prologue and the `blt-` replaced with a `bge+ .Lnormal_func_body`
839// instead.
840// -) If either the addis or addi is not needed due to the stack size being
841// smaller then 32K or a multiple of 64K they will be replaced with a nop,
842// but there will always be 2 instructions the linker can overwrite for the
843// adjusted stack size.
844//
845// The linkers job here is to increase the stack size used in the addis/addi
846// pair by split-stack-size-adjust.
847// addis r12, r1, ha(-stack-frame size - split-stack-adjust-size)
848// addi r12, r12, l(-stack-frame size - split-stack-adjust-size)
849bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
850 uint8_t StOther) const {
851 // If the caller has a global entry point adjust the buffer past it. The start
852 // of the split-stack prologue will be at the local entry point.
853 Loc += getPPC64GlobalEntryToLocalEntryOffset(StOther);
854
855 // At the very least we expect to see a load of some split-stack data from the
856 // tcb, and 2 instructions that calculate the ending stack address this
857 // function will require. If there is not enough room for at least 3
858 // instructions it can't be a split-stack prologue.
859 if (Loc + 12 >= End)
860 return false;
861
862 // First instruction must be `ld r0, -0x7000-64(r13)`
863 if (read32(Loc) != 0xe80d8fc0)
864 return false;
865
866 int16_t HiImm = 0;
867 int16_t LoImm = 0;
868 // First instruction can be either an addis if the frame size is larger then
869 // 32K, or an addi if the size is less then 32K.
870 int32_t FirstInstr = read32(Loc + 4);
871 if (getPrimaryOpCode(FirstInstr) == 15) {
872 HiImm = FirstInstr & 0xFFFF;
873 } else if (getPrimaryOpCode(FirstInstr) == 14) {
874 LoImm = FirstInstr & 0xFFFF;
875 } else {
876 return false;
877 }
878
879 // Second instruction is either an addi or a nop. If the first instruction was
880 // an addi then LoImm is set and the second instruction must be a nop.
881 uint32_t SecondInstr = read32(Loc + 8);
882 if (!LoImm && getPrimaryOpCode(SecondInstr) == 14) {
883 LoImm = SecondInstr & 0xFFFF;
884 } else if (SecondInstr != 0x60000000) {
885 return false;
886 }
887
888 // The register operands of the first instruction should be the stack-pointer
889 // (r1) as the input (RA) and r12 as the output (RT). If the second
890 // instruction is not a nop, then it should use r12 as both input and output.
891 auto CheckRegOperands = [](uint32_t Instr, uint8_t ExpectedRT,
892 uint8_t ExpectedRA) {
893 return ((Instr & 0x3E00000) >> 21 == ExpectedRT) &&
894 ((Instr & 0x1F0000) >> 16 == ExpectedRA);
895 };
896 if (!CheckRegOperands(FirstInstr, 12, 1))
897 return false;
898 if (SecondInstr != 0x60000000 && !CheckRegOperands(SecondInstr, 12, 12))
899 return false;
900
901 int32_t StackFrameSize = (HiImm * 65536) + LoImm;
902 // Check that the adjusted size doesn't overflow what we can represent with 2
903 // instructions.
904 if (StackFrameSize < Config->SplitStackAdjustSize + INT32_MIN) {
905 error(getErrorLocation(Loc) + "split-stack prologue adjustment overflows");
906 return false;
907 }
908
909 int32_t AdjustedStackFrameSize =
910 StackFrameSize - Config->SplitStackAdjustSize;
911
912 LoImm = AdjustedStackFrameSize & 0xFFFF;
913 HiImm = (AdjustedStackFrameSize + 0x8000) >> 16;
914 if (HiImm) {
915 write32(Loc + 4, 0x3D810000 | (uint16_t)HiImm);
916 // If the low immediate is zero the second instruction will be a nop.
917 SecondInstr = LoImm ? 0x398C0000 | (uint16_t)LoImm : 0x60000000;
918 write32(Loc + 8, SecondInstr);
919 } else {
920 // addi r12, r1, imm
921 write32(Loc + 4, (0x39810000) | (uint16_t)LoImm);
922 write32(Loc + 8, 0x60000000);
923 }
924
925 return true;
926}
927
529TargetInfo *elf::getPPC64TargetInfo() {928TargetInfo *elf::getPPC64TargetInfo() {
530 static PPC64 Target;929 static PPC64 Target;
531 return &Target;930 return &Target;
deps/lld/ELF/Arch/RISCV.cpp created+279
...@@ -0,0 +1,279 @@
1//===- RISCV.cpp ----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputFiles.h"
11#include "Target.h"
12
13using namespace llvm;
14using namespace llvm::object;
15using namespace llvm::support::endian;
16using namespace llvm::ELF;
17using namespace lld;
18using namespace lld::elf;
19
20namespace {
21
22class RISCV final : public TargetInfo {
23public:
24 RISCV();
25 uint32_t calcEFlags() const override;
26 RelExpr getRelExpr(RelType Type, const Symbol &S,
27 const uint8_t *Loc) const override;
28 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
29};
30
31} // end anonymous namespace
32
33RISCV::RISCV() { NoneRel = R_RISCV_NONE; }
34
35static uint32_t getEFlags(InputFile *F) {
36 if (Config->Is64)
37 return cast<ObjFile<ELF64LE>>(F)->getObj().getHeader()->e_flags;
38 return cast<ObjFile<ELF32LE>>(F)->getObj().getHeader()->e_flags;
39}
40
41uint32_t RISCV::calcEFlags() const {
42 assert(!ObjectFiles.empty());
43
44 uint32_t Target = getEFlags(ObjectFiles.front());
45
46 for (InputFile *F : ObjectFiles) {
47 uint32_t EFlags = getEFlags(F);
48 if (EFlags & EF_RISCV_RVC)
49 Target |= EF_RISCV_RVC;
50
51 if ((EFlags & EF_RISCV_FLOAT_ABI) != (Target & EF_RISCV_FLOAT_ABI))
52 error(toString(F) +
53 ": cannot link object files with different floating-point ABI");
54
55 if ((EFlags & EF_RISCV_RVE) != (Target & EF_RISCV_RVE))
56 error(toString(F) +
57 ": cannot link object files with different EF_RISCV_RVE");
58 }
59
60 return Target;
61}
62
63RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
64 const uint8_t *Loc) const {
65 switch (Type) {
66 case R_RISCV_JAL:
67 case R_RISCV_BRANCH:
68 case R_RISCV_CALL:
69 case R_RISCV_PCREL_HI20:
70 case R_RISCV_RVC_BRANCH:
71 case R_RISCV_RVC_JUMP:
72 case R_RISCV_32_PCREL:
73 return R_PC;
74 case R_RISCV_PCREL_LO12_I:
75 case R_RISCV_PCREL_LO12_S:
76 return R_RISCV_PC_INDIRECT;
77 case R_RISCV_RELAX:
78 case R_RISCV_ALIGN:
79 return R_HINT;
80 default:
81 return R_ABS;
82 }
83}
84
85// Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63.
86static uint32_t extractBits(uint64_t V, uint32_t Begin, uint32_t End) {
87 return (V & ((1ULL << (Begin + 1)) - 1)) >> End;
88}
89
90void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
91 const uint64_t Val) const {
92 switch (Type) {
93 case R_RISCV_32:
94 write32le(Loc, Val);
95 return;
96 case R_RISCV_64:
97 write64le(Loc, Val);
98 return;
99
100 case R_RISCV_RVC_BRANCH: {
101 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 8, Type);
102 checkAlignment(Loc, Val, 2, Type);
103 uint16_t Insn = read16le(Loc) & 0xE383;
104 uint16_t Imm8 = extractBits(Val, 8, 8) << 12;
105 uint16_t Imm4_3 = extractBits(Val, 4, 3) << 10;
106 uint16_t Imm7_6 = extractBits(Val, 7, 6) << 5;
107 uint16_t Imm2_1 = extractBits(Val, 2, 1) << 3;
108 uint16_t Imm5 = extractBits(Val, 5, 5) << 2;
109 Insn |= Imm8 | Imm4_3 | Imm7_6 | Imm2_1 | Imm5;
110
111 write16le(Loc, Insn);
112 return;
113 }
114
115 case R_RISCV_RVC_JUMP: {
116 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 11, Type);
117 checkAlignment(Loc, Val, 2, Type);
118 uint16_t Insn = read16le(Loc) & 0xE003;
119 uint16_t Imm11 = extractBits(Val, 11, 11) << 12;
120 uint16_t Imm4 = extractBits(Val, 4, 4) << 11;
121 uint16_t Imm9_8 = extractBits(Val, 9, 8) << 9;
122 uint16_t Imm10 = extractBits(Val, 10, 10) << 8;
123 uint16_t Imm6 = extractBits(Val, 6, 6) << 7;
124 uint16_t Imm7 = extractBits(Val, 7, 7) << 6;
125 uint16_t Imm3_1 = extractBits(Val, 3, 1) << 3;
126 uint16_t Imm5 = extractBits(Val, 5, 5) << 2;
127 Insn |= Imm11 | Imm4 | Imm9_8 | Imm10 | Imm6 | Imm7 | Imm3_1 | Imm5;
128
129 write16le(Loc, Insn);
130 return;
131 }
132
133 case R_RISCV_RVC_LUI: {
134 int32_t Imm = ((Val + 0x800) >> 12);
135 checkUInt(Loc, Imm, 6, Type);
136 if (Imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0`
137 write16le(Loc, (read16le(Loc) & 0x0F83) | 0x4000);
138 } else {
139 uint16_t Imm17 = extractBits(Val + 0x800, 17, 17) << 12;
140 uint16_t Imm16_12 = extractBits(Val + 0x800, 16, 12) << 2;
141 write16le(Loc, (read16le(Loc) & 0xEF83) | Imm17 | Imm16_12);
142 }
143 return;
144 }
145
146 case R_RISCV_JAL: {
147 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 20, Type);
148 checkAlignment(Loc, Val, 2, Type);
149
150 uint32_t Insn = read32le(Loc) & 0xFFF;
151 uint32_t Imm20 = extractBits(Val, 20, 20) << 31;
152 uint32_t Imm10_1 = extractBits(Val, 10, 1) << 21;
153 uint32_t Imm11 = extractBits(Val, 11, 11) << 20;
154 uint32_t Imm19_12 = extractBits(Val, 19, 12) << 12;
155 Insn |= Imm20 | Imm10_1 | Imm11 | Imm19_12;
156
157 write32le(Loc, Insn);
158 return;
159 }
160
161 case R_RISCV_BRANCH: {
162 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 12, Type);
163 checkAlignment(Loc, Val, 2, Type);
164
165 uint32_t Insn = read32le(Loc) & 0x1FFF07F;
166 uint32_t Imm12 = extractBits(Val, 12, 12) << 31;
167 uint32_t Imm10_5 = extractBits(Val, 10, 5) << 25;
168 uint32_t Imm4_1 = extractBits(Val, 4, 1) << 8;
169 uint32_t Imm11 = extractBits(Val, 11, 11) << 7;
170 Insn |= Imm12 | Imm10_5 | Imm4_1 | Imm11;
171
172 write32le(Loc, Insn);
173 return;
174 }
175
176 // auipc + jalr pair
177 case R_RISCV_CALL: {
178 checkInt(Loc, Val, 32, Type);
179 if (isInt<32>(Val)) {
180 relocateOne(Loc, R_RISCV_PCREL_HI20, Val);
181 relocateOne(Loc + 4, R_RISCV_PCREL_LO12_I, Val);
182 }
183 return;
184 }
185
186 case R_RISCV_PCREL_HI20:
187 case R_RISCV_HI20: {
188 checkInt(Loc, Val, 32, Type);
189 uint32_t Hi = Val + 0x800;
190 write32le(Loc, (read32le(Loc) & 0xFFF) | (Hi & 0xFFFFF000));
191 return;
192 }
193
194 case R_RISCV_PCREL_LO12_I:
195 case R_RISCV_LO12_I: {
196 checkInt(Loc, Val, 32, Type);
197 uint32_t Hi = Val + 0x800;
198 uint32_t Lo = Val - (Hi & 0xFFFFF000);
199 write32le(Loc, (read32le(Loc) & 0xFFFFF) | ((Lo & 0xFFF) << 20));
200 return;
201 }
202
203 case R_RISCV_PCREL_LO12_S:
204 case R_RISCV_LO12_S: {
205 checkInt(Loc, Val, 32, Type);
206 uint32_t Hi = Val + 0x800;
207 uint32_t Lo = Val - (Hi & 0xFFFFF000);
208 uint32_t Imm11_5 = extractBits(Lo, 11, 5) << 25;
209 uint32_t Imm4_0 = extractBits(Lo, 4, 0) << 7;
210 write32le(Loc, (read32le(Loc) & 0x1FFF07F) | Imm11_5 | Imm4_0);
211 return;
212 }
213
214 case R_RISCV_ADD8:
215 *Loc += Val;
216 return;
217 case R_RISCV_ADD16:
218 write16le(Loc, read16le(Loc) + Val);
219 return;
220 case R_RISCV_ADD32:
221 write32le(Loc, read32le(Loc) + Val);
222 return;
223 case R_RISCV_ADD64:
224 write64le(Loc, read64le(Loc) + Val);
225 return;
226 case R_RISCV_SUB6:
227 *Loc = (*Loc & 0xc0) | (((*Loc & 0x3f) - Val) & 0x3f);
228 return;
229 case R_RISCV_SUB8:
230 *Loc -= Val;
231 return;
232 case R_RISCV_SUB16:
233 write16le(Loc, read16le(Loc) - Val);
234 return;
235 case R_RISCV_SUB32:
236 write32le(Loc, read32le(Loc) - Val);
237 return;
238 case R_RISCV_SUB64:
239 write64le(Loc, read64le(Loc) - Val);
240 return;
241 case R_RISCV_SET6:
242 *Loc = (*Loc & 0xc0) | (Val & 0x3f);
243 return;
244 case R_RISCV_SET8:
245 *Loc = Val;
246 return;
247 case R_RISCV_SET16:
248 write16le(Loc, Val);
249 return;
250 case R_RISCV_SET32:
251 case R_RISCV_32_PCREL:
252 write32le(Loc, Val);
253 return;
254
255 case R_RISCV_ALIGN:
256 case R_RISCV_RELAX:
257 return; // Ignored (for now)
258 case R_RISCV_NONE:
259 return; // Do nothing
260
261 // These are handled by the dynamic linker
262 case R_RISCV_RELATIVE:
263 case R_RISCV_COPY:
264 case R_RISCV_JUMP_SLOT:
265 // GP-relative relocations are only produced after relaxation, which
266 // we don't support for now
267 case R_RISCV_GPREL_I:
268 case R_RISCV_GPREL_S:
269 default:
270 error(getErrorLocation(Loc) +
271 "unimplemented relocation: " + toString(Type));
272 return;
273 }
274}
275
276TargetInfo *elf::getRISCVTargetInfo() {
277 static RISCV Target;
278 return &Target;
279}
deps/lld/ELF/Arch/SPARCV9.cpp+1
...@@ -35,6 +35,7 @@ public:...@@ -35,6 +35,7 @@ public:
35SPARCV9::SPARCV9() {35SPARCV9::SPARCV9() {
36 CopyRel = R_SPARC_COPY;36 CopyRel = R_SPARC_COPY;
37 GotRel = R_SPARC_GLOB_DAT;37 GotRel = R_SPARC_GLOB_DAT;
38 NoneRel = R_SPARC_NONE;
38 PltRel = R_SPARC_JMP_SLOT;39 PltRel = R_SPARC_JMP_SLOT;
39 RelativeRel = R_SPARC_RELATIVE;40 RelativeRel = R_SPARC_RELATIVE;
40 GotEntrySize = 8;41 GotEntrySize = 8;
deps/lld/ELF/Arch/X86.cpp+15-10
...@@ -48,6 +48,7 @@ public:...@@ -48,6 +48,7 @@ public:
48X86::X86() {48X86::X86() {
49 CopyRel = R_386_COPY;49 CopyRel = R_386_COPY;
50 GotRel = R_386_GLOB_DAT;50 GotRel = R_386_GLOB_DAT;
51 NoneRel = R_386_NONE;
51 PltRel = R_386_JUMP_SLOT;52 PltRel = R_386_JUMP_SLOT;
52 IRelativeRel = R_386_IRELATIVE;53 IRelativeRel = R_386_IRELATIVE;
53 RelativeRel = R_386_RELATIVE;54 RelativeRel = R_386_RELATIVE;
...@@ -59,7 +60,11 @@ X86::X86() {...@@ -59,7 +60,11 @@ X86::X86() {
59 PltEntrySize = 16;60 PltEntrySize = 16;
60 PltHeaderSize = 16;61 PltHeaderSize = 16;
61 TlsGdRelaxSkip = 2;62 TlsGdRelaxSkip = 2;
62 TrapInstr = 0xcccccccc; // 0xcc = INT363 TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
64
65 // Align to the non-PAE large page size (known as a superpage or huge page).
66 // FreeBSD automatically promotes large, superpage-aligned allocations.
67 DefaultImageBase = 0x400000;
63}68}
6469
65static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }70static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
...@@ -152,7 +157,7 @@ RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,...@@ -152,7 +157,7 @@ RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,
152}157}
153158
154void X86::writeGotPltHeader(uint8_t *Buf) const {159void X86::writeGotPltHeader(uint8_t *Buf) const {
155 write32le(Buf, InX::Dynamic->getVA());160 write32le(Buf, In.Dynamic->getVA());
156}161}
157162
158void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {163void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
...@@ -183,8 +188,8 @@ void X86::writePltHeader(uint8_t *Buf) const {...@@ -183,8 +188,8 @@ void X86::writePltHeader(uint8_t *Buf) const {
183 };188 };
184 memcpy(Buf, V, sizeof(V));189 memcpy(Buf, V, sizeof(V));
185190
186 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();191 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
187 uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;192 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
188 write32le(Buf + 2, GotPlt + 4);193 write32le(Buf + 2, GotPlt + 4);
189 write32le(Buf + 8, GotPlt + 8);194 write32le(Buf + 8, GotPlt + 8);
190 return;195 return;
...@@ -196,7 +201,7 @@ void X86::writePltHeader(uint8_t *Buf) const {...@@ -196,7 +201,7 @@ void X86::writePltHeader(uint8_t *Buf) const {
196 0x90, 0x90, 0x90, 0x90, // nop201 0x90, 0x90, 0x90, 0x90, // nop
197 };202 };
198 memcpy(Buf, PltData, sizeof(PltData));203 memcpy(Buf, PltData, sizeof(PltData));
199 uint32_t GotPlt = InX::GotPlt->getVA();204 uint32_t GotPlt = In.GotPlt->getVA();
200 write32le(Buf + 2, GotPlt + 4);205 write32le(Buf + 2, GotPlt + 4);
201 write32le(Buf + 8, GotPlt + 8);206 write32le(Buf + 8, GotPlt + 8);
202}207}
...@@ -213,7 +218,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,...@@ -213,7 +218,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
213218
214 if (Config->Pic) {219 if (Config->Pic) {
215 // jmp *foo@GOT(%ebx)220 // jmp *foo@GOT(%ebx)
216 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();221 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
217 Buf[1] = 0xa3;222 Buf[1] = 0xa3;
218 write32le(Buf + 2, GotPltEntryAddr - Ebx);223 write32le(Buf + 2, GotPltEntryAddr - Ebx);
219 } else {224 } else {
...@@ -447,8 +452,8 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const {...@@ -447,8 +452,8 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const {
447 };452 };
448 memcpy(Buf, Insn, sizeof(Insn));453 memcpy(Buf, Insn, sizeof(Insn));
449454
450 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();455 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
451 uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;456 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
452 write32le(Buf + 2, GotPlt + 4);457 write32le(Buf + 2, GotPlt + 4);
453 write32le(Buf + 9, GotPlt + 8);458 write32le(Buf + 9, GotPlt + 8);
454}459}
...@@ -467,7 +472,7 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,...@@ -467,7 +472,7 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
467 };472 };
468 memcpy(Buf, Insn, sizeof(Insn));473 memcpy(Buf, Insn, sizeof(Insn));
469474
470 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();475 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
471 unsigned Off = getPltEntryOffset(Index);476 unsigned Off = getPltEntryOffset(Index);
472 write32le(Buf + 3, GotPltEntryAddr - Ebx);477 write32le(Buf + 3, GotPltEntryAddr - Ebx);
473 write32le(Buf + 8, -Off - 12 + 32);478 write32le(Buf + 8, -Off - 12 + 32);
...@@ -506,7 +511,7 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {...@@ -506,7 +511,7 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
506 };511 };
507 memcpy(Buf, Insn, sizeof(Insn));512 memcpy(Buf, Insn, sizeof(Insn));
508513
509 uint32_t GotPlt = InX::GotPlt->getVA();514 uint32_t GotPlt = In.GotPlt->getVA();
510 write32le(Buf + 2, GotPlt + 4);515 write32le(Buf + 2, GotPlt + 4);
511 write32le(Buf + 8, GotPlt + 8);516 write32le(Buf + 8, GotPlt + 8);
512}517}
deps/lld/ELF/Arch/X86_64.cpp+59-32
...@@ -43,8 +43,8 @@ public:...@@ -43,8 +43,8 @@ public:
43 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;43 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
44 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;44 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
45 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;45 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
46 bool adjustPrologueForCrossSplitStack(uint8_t *Loc,46 bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
47 uint8_t *End) const override;47 uint8_t StOther) const override;
4848
49private:49private:
50 void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,50 void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
...@@ -55,6 +55,7 @@ private:...@@ -55,6 +55,7 @@ private:
55template <class ELFT> X86_64<ELFT>::X86_64() {55template <class ELFT> X86_64<ELFT>::X86_64() {
56 CopyRel = R_X86_64_COPY;56 CopyRel = R_X86_64_COPY;
57 GotRel = R_X86_64_GLOB_DAT;57 GotRel = R_X86_64_GLOB_DAT;
58 NoneRel = R_X86_64_NONE;
58 PltRel = R_X86_64_JUMP_SLOT;59 PltRel = R_X86_64_JUMP_SLOT;
59 RelativeRel = R_X86_64_RELATIVE;60 RelativeRel = R_X86_64_RELATIVE;
60 IRelativeRel = R_X86_64_IRELATIVE;61 IRelativeRel = R_X86_64_IRELATIVE;
...@@ -66,7 +67,7 @@ template <class ELFT> X86_64<ELFT>::X86_64() {...@@ -66,7 +67,7 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
66 PltEntrySize = 16;67 PltEntrySize = 16;
67 PltHeaderSize = 16;68 PltHeaderSize = 16;
68 TlsGdRelaxSkip = 2;69 TlsGdRelaxSkip = 2;
69 TrapInstr = 0xcccccccc; // 0xcc = INT370 TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
7071
71 // Align to the large page size (known as a superpage or huge page).72 // Align to the large page size (known as a superpage or huge page).
72 // FreeBSD automatically promotes large, superpage-aligned allocations.73 // FreeBSD automatically promotes large, superpage-aligned allocations.
...@@ -124,7 +125,7 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const {...@@ -124,7 +125,7 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
124 // required, but it is documented in the psabi and the glibc dynamic linker125 // required, but it is documented in the psabi and the glibc dynamic linker
125 // seems to use it (note that this is relevant for linking ld.so, not any126 // seems to use it (note that this is relevant for linking ld.so, not any
126 // other program).127 // other program).
127 write64le(Buf, InX::Dynamic->getVA());128 write64le(Buf, In.Dynamic->getVA());
128}129}
129130
130template <class ELFT>131template <class ELFT>
...@@ -140,8 +141,8 @@ template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {...@@ -140,8 +141,8 @@ template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {
140 0x0f, 0x1f, 0x40, 0x00, // nop141 0x0f, 0x1f, 0x40, 0x00, // nop
141 };142 };
142 memcpy(Buf, PltData, sizeof(PltData));143 memcpy(Buf, PltData, sizeof(PltData));
143 uint64_t GotPlt = InX::GotPlt->getVA();144 uint64_t GotPlt = In.GotPlt->getVA();
144 uint64_t Plt = InX::Plt->getVA();145 uint64_t Plt = In.Plt->getVA();
145 write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8146 write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
146 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16147 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
147}148}
...@@ -263,15 +264,6 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type,...@@ -263,15 +264,6 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
263template <class ELFT>264template <class ELFT>
264void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,265void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
265 uint64_t Val) const {266 uint64_t Val) const {
266 // Convert
267 // leaq bar@tlsld(%rip), %rdi
268 // callq __tls_get_addr@PLT
269 // leaq bar@dtpoff(%rax), %rcx
270 // to
271 // .word 0x6666
272 // .byte 0x66
273 // mov %fs:0,%rax
274 // leaq bar@tpoff(%rax), %rcx
275 if (Type == R_X86_64_DTPOFF64) {267 if (Type == R_X86_64_DTPOFF64) {
276 write64le(Loc, Val);268 write64le(Loc, Val);
277 return;269 return;
...@@ -286,7 +278,37 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,...@@ -286,7 +278,37 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
286 0x66, // .byte 0x66278 0x66, // .byte 0x66
287 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax279 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
288 };280 };
289 memcpy(Loc - 3, Inst, sizeof(Inst));281
282 if (Loc[4] == 0xe8) {
283 // Convert
284 // leaq bar@tlsld(%rip), %rdi # 48 8d 3d <Loc>
285 // callq __tls_get_addr@PLT # e8 <disp32>
286 // leaq bar@dtpoff(%rax), %rcx
287 // to
288 // .word 0x6666
289 // .byte 0x66
290 // mov %fs:0,%rax
291 // leaq bar@tpoff(%rax), %rcx
292 memcpy(Loc - 3, Inst, sizeof(Inst));
293 return;
294 }
295
296 if (Loc[4] == 0xff && Loc[5] == 0x15) {
297 // Convert
298 // leaq x@tlsld(%rip),%rdi # 48 8d 3d <Loc>
299 // call *__tls_get_addr@GOTPCREL(%rip) # ff 15 <disp32>
300 // to
301 // .long 0x66666666
302 // movq %fs:0,%rax
303 // See "Table 11.9: LD -> LE Code Transition (LP64)" in
304 // https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
305 Loc[-3] = 0x66;
306 memcpy(Loc - 2, Inst, sizeof(Inst));
307 return;
308 }
309
310 error(getErrorLocation(Loc - 3) +
311 "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
290}312}
291313
292template <class ELFT>314template <class ELFT>
...@@ -481,23 +503,27 @@ namespace {...@@ -481,23 +503,27 @@ namespace {
481// B) Or a load of a stack pointer offset with an lea to r10 or r11.503// B) Or a load of a stack pointer offset with an lea to r10 or r11.
482template <>504template <>
483bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,505bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
484 uint8_t *End) const {506 uint8_t *End,
507 uint8_t StOther) const {
508 if (Loc + 8 >= End)
509 return false;
510
485 // Replace "cmp %fs:0x70,%rsp" and subsequent branch511 // Replace "cmp %fs:0x70,%rsp" and subsequent branch
486 // with "stc, nopl 0x0(%rax,%rax,1)"512 // with "stc, nopl 0x0(%rax,%rax,1)"
487 if (Loc + 8 < End && memcmp(Loc, "\x64\x48\x3b\x24\x25", 4) == 0) {513 if (memcmp(Loc, "\x64\x48\x3b\x24\x25", 5) == 0) {
488 memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);514 memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
489 return true;515 return true;
490 }516 }
491517
492 // Adjust "lea -0x200(%rsp),%r10" to lea "-0x4200(%rsp),%r10"518 // Adjust "lea X(%rsp),%rYY" to lea "(X - 0x4000)(%rsp),%rYY" where rYY could
493 if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x94\x24\x00\xfe\xff", 7) == 0) {519 // be r10 or r11. The lea instruction feeds a subsequent compare which checks
494 memcpy(Loc, "\x4c\x8d\x94\x24\x00\xbe\xff", 7);520 // if there is X available stack space. Making X larger effectively reserves
495 return true;521 // that much additional space. The stack grows downward so subtract the value.
496 }522 if (memcmp(Loc, "\x4c\x8d\x94\x24", 4) == 0 ||
497523 memcmp(Loc, "\x4c\x8d\x9c\x24", 4) == 0) {
498 // Adjust "lea -0x200(%rsp),%r11" to lea "-0x4200(%rsp),%r11"524 // The offset bytes are encoded four bytes after the start of the
499 if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x9c\x24\x00\xfe\xff", 7) == 0) {525 // instruction.
500 memcpy(Loc, "\x4c\x8d\x9c\x24\x00\xbe\xff", 7);526 write32le(Loc + 4, read32le(Loc + 4) - 0x4000);
501 return true;527 return true;
502 }528 }
503 return false;529 return false;
...@@ -505,7 +531,8 @@ bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,...@@ -505,7 +531,8 @@ bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
505531
506template <>532template <>
507bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,533bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
508 uint8_t *End) const {534 uint8_t *End,
535 uint8_t StOther) const {
509 llvm_unreachable("Target doesn't support split stacks.");536 llvm_unreachable("Target doesn't support split stacks.");
510}537}
511538
...@@ -566,8 +593,8 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {...@@ -566,8 +593,8 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
566 };593 };
567 memcpy(Buf, Insn, sizeof(Insn));594 memcpy(Buf, Insn, sizeof(Insn));
568595
569 uint64_t GotPlt = InX::GotPlt->getVA();596 uint64_t GotPlt = In.GotPlt->getVA();
570 uint64_t Plt = InX::Plt->getVA();597 uint64_t Plt = In.Plt->getVA();
571 write32le(Buf + 2, GotPlt - Plt - 6 + 8);598 write32le(Buf + 2, GotPlt - Plt - 6 + 8);
572 write32le(Buf + 9, GotPlt - Plt - 13 + 16);599 write32le(Buf + 9, GotPlt - Plt - 13 + 16);
573}600}
...@@ -586,7 +613,7 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,...@@ -586,7 +613,7 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
586 };613 };
587 memcpy(Buf, Insn, sizeof(Insn));614 memcpy(Buf, Insn, sizeof(Insn));
588615
589 uint64_t Off = TargetInfo::getPltEntryOffset(Index);616 uint64_t Off = getPltEntryOffset(Index);
590617
591 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);618 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
592 write32le(Buf + 8, -Off - 12 + 32);619 write32le(Buf + 8, -Off - 12 + 32);
...@@ -629,7 +656,7 @@ void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,...@@ -629,7 +656,7 @@ void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
629 memcpy(Buf, Insn, sizeof(Insn));656 memcpy(Buf, Insn, sizeof(Insn));
630657
631 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);658 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
632 write32le(Buf + 8, -TargetInfo::getPltEntryOffset(Index) - 12);659 write32le(Buf + 8, -getPltEntryOffset(Index) - 12);
633}660}
634661
635template <class ELFT> static TargetInfo *getTargetInfo() {662template <class ELFT> static TargetInfo *getTargetInfo() {
deps/lld/ELF/CMakeLists.txt+3-1
...@@ -15,17 +15,19 @@ add_lld_library(lldELF...@@ -15,17 +15,19 @@ add_lld_library(lldELF
15 Arch/Hexagon.cpp15 Arch/Hexagon.cpp
16 Arch/Mips.cpp16 Arch/Mips.cpp
17 Arch/MipsArchTree.cpp17 Arch/MipsArchTree.cpp
18 Arch/MSP430.cpp
18 Arch/PPC.cpp19 Arch/PPC.cpp
19 Arch/PPC64.cpp20 Arch/PPC64.cpp
21 Arch/RISCV.cpp
20 Arch/SPARCV9.cpp22 Arch/SPARCV9.cpp
21 Arch/X86.cpp23 Arch/X86.cpp
22 Arch/X86_64.cpp24 Arch/X86_64.cpp
23 CallGraphSort.cpp25 CallGraphSort.cpp
26 DWARF.cpp
24 Driver.cpp27 Driver.cpp
25 DriverUtils.cpp28 DriverUtils.cpp
26 EhFrame.cpp29 EhFrame.cpp
27 Filesystem.cpp30 Filesystem.cpp
28 GdbIndex.cpp
29 ICF.cpp31 ICF.cpp
30 InputFiles.cpp32 InputFiles.cpp
31 InputSection.cpp33 InputSection.cpp
deps/lld/ELF/CallGraphSort.cpp+21-30
...@@ -57,10 +57,7 @@ struct Edge {...@@ -57,10 +57,7 @@ struct Edge {
57};57};
5858
59struct Cluster {59struct Cluster {
60 Cluster(int Sec, size_t S) {60 Cluster(int Sec, size_t S) : Sections{Sec}, Size(S) {}
61 Sections.push_back(Sec);
62 Size = S;
63 }
6461
65 double getDensity() const {62 double getDensity() const {
66 if (Size == 0)63 if (Size == 0)
...@@ -72,7 +69,7 @@ struct Cluster {...@@ -72,7 +69,7 @@ struct Cluster {
72 size_t Size = 0;69 size_t Size = 0;
73 uint64_t Weight = 0;70 uint64_t Weight = 0;
74 uint64_t InitialWeight = 0;71 uint64_t InitialWeight = 0;
75 std::vector<Edge> Preds;72 Edge BestPred = {-1, 0};
76};73};
7774
78class CallGraphSort {75class CallGraphSort {
...@@ -96,12 +93,14 @@ constexpr int MAX_DENSITY_DEGRADATION = 8;...@@ -96,12 +93,14 @@ constexpr int MAX_DENSITY_DEGRADATION = 8;
96constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024;93constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024;
97} // end anonymous namespace94} // end anonymous namespace
9895
96typedef std::pair<const InputSectionBase *, const InputSectionBase *>
97 SectionPair;
98
99// Take the edge list in Config->CallGraphProfile, resolve symbol names to99// Take the edge list in Config->CallGraphProfile, resolve symbol names to
100// Symbols, and generate a graph between InputSections with the provided100// Symbols, and generate a graph between InputSections with the provided
101// weights.101// weights.
102CallGraphSort::CallGraphSort() {102CallGraphSort::CallGraphSort() {
103 llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,103 MapVector<SectionPair, uint64_t> &Profile = Config->CallGraphProfile;
104 uint64_t> &Profile = Config->CallGraphProfile;
105 DenseMap<const InputSectionBase *, int> SecToCluster;104 DenseMap<const InputSectionBase *, int> SecToCluster;
106105
107 auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {106 auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {
...@@ -114,7 +113,7 @@ CallGraphSort::CallGraphSort() {...@@ -114,7 +113,7 @@ CallGraphSort::CallGraphSort() {
114 };113 };
115114
116 // Create the graph.115 // Create the graph.
117 for (const auto &C : Profile) {116 for (std::pair<SectionPair, uint64_t> &C : Profile) {
118 const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);117 const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);
119 const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);118 const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);
120 uint64_t Weight = C.second;119 uint64_t Weight = C.second;
...@@ -136,8 +135,12 @@ CallGraphSort::CallGraphSort() {...@@ -136,8 +135,12 @@ CallGraphSort::CallGraphSort() {
136 if (From == To)135 if (From == To)
137 continue;136 continue;
138137
139 // Add an edge138 // Remember the best edge.
140 Clusters[To].Preds.push_back({From, Weight});139 Cluster &ToC = Clusters[To];
140 if (ToC.BestPred.From == -1 || ToC.BestPred.Weight < Weight) {
141 ToC.BestPred.From = From;
142 ToC.BestPred.Weight = Weight;
143 }
141 }144 }
142 for (Cluster &C : Clusters)145 for (Cluster &C : Clusters)
143 C.InitialWeight = C.Weight;146 C.InitialWeight = C.Weight;
...@@ -146,9 +149,7 @@ CallGraphSort::CallGraphSort() {...@@ -146,9 +149,7 @@ CallGraphSort::CallGraphSort() {
146// It's bad to merge clusters which would degrade the density too much.149// It's bad to merge clusters which would degrade the density too much.
147static bool isNewDensityBad(Cluster &A, Cluster &B) {150static bool isNewDensityBad(Cluster &A, Cluster &B) {
148 double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);151 double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);
149 if (NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION)152 return NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION;
150 return true;
151 return false;
152}153}
153154
154static void mergeClusters(Cluster &Into, Cluster &From) {155static void mergeClusters(Cluster &Into, Cluster &From) {
...@@ -167,9 +168,9 @@ void CallGraphSort::groupClusters() {...@@ -167,9 +168,9 @@ void CallGraphSort::groupClusters() {
167 std::vector<int> SortedSecs(Clusters.size());168 std::vector<int> SortedSecs(Clusters.size());
168 std::vector<Cluster *> SecToCluster(Clusters.size());169 std::vector<Cluster *> SecToCluster(Clusters.size());
169170
170 for (int SI = 0, SE = Clusters.size(); SI != SE; ++SI) {171 for (size_t I = 0; I < Clusters.size(); ++I) {
171 SortedSecs[SI] = SI;172 SortedSecs[I] = I;
172 SecToCluster[SI] = &Clusters[SI];173 SecToCluster[I] = &Clusters[I];
173 }174 }
174175
175 std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {176 std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
...@@ -181,21 +182,11 @@ void CallGraphSort::groupClusters() {...@@ -181,21 +182,11 @@ void CallGraphSort::groupClusters() {
181 // been merged into another cluster yet.182 // been merged into another cluster yet.
182 Cluster &C = Clusters[SI];183 Cluster &C = Clusters[SI];
183184
184 int BestPred = -1;185 // Don't consider merging if the edge is unlikely.
185 uint64_t BestWeight = 0;186 if (C.BestPred.From == -1 || C.BestPred.Weight * 10 <= C.InitialWeight)
186
187 for (Edge &E : C.Preds) {
188 if (BestPred == -1 || E.Weight > BestWeight) {
189 BestPred = E.From;
190 BestWeight = E.Weight;
191 }
192 }
193
194 // don't consider merging if the edge is unlikely.
195 if (BestWeight * 10 <= C.InitialWeight)
196 continue;187 continue;
197188
198 Cluster *PredC = SecToCluster[BestPred];189 Cluster *PredC = SecToCluster[C.BestPred.From];
199 if (PredC == &C)190 if (PredC == &C)
200 continue;191 continue;
201192
...@@ -229,7 +220,7 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {...@@ -229,7 +220,7 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
229 groupClusters();220 groupClusters();
230221
231 // Generate order.222 // Generate order.
232 llvm::DenseMap<const InputSectionBase *, int> OrderMap;223 DenseMap<const InputSectionBase *, int> OrderMap;
233 ssize_t CurOrder = 1;224 ssize_t CurOrder = 1;
234225
235 for (const Cluster &C : Clusters)226 for (const Cluster &C : Clusters)
deps/lld/ELF/Config.h+11-1
...@@ -47,7 +47,7 @@ enum class ICFLevel { None, Safe, All };...@@ -47,7 +47,7 @@ enum class ICFLevel { None, Safe, All };
47enum class StripPolicy { None, All, Debug };47enum class StripPolicy { None, All, Debug };
4848
49// For --unresolved-symbols.49// For --unresolved-symbols.
50enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll };50enum class UnresolvedPolicy { ReportError, Warn, Ignore };
5151
52// For --orphan-handling.52// For --orphan-handling.
53enum class OrphanHandlingPolicy { Place, Warn, Error };53enum class OrphanHandlingPolicy { Place, Warn, Error };
...@@ -127,6 +127,7 @@ struct Configuration {...@@ -127,6 +127,7 @@ struct Configuration {
127 bool AsNeeded = false;127 bool AsNeeded = false;
128 bool Bsymbolic;128 bool Bsymbolic;
129 bool BsymbolicFunctions;129 bool BsymbolicFunctions;
130 bool CallGraphProfileSort;
130 bool CheckSections;131 bool CheckSections;
131 bool CompressDebugSections;132 bool CompressDebugSections;
132 bool Cref;133 bool Cref;
...@@ -134,11 +135,13 @@ struct Configuration {...@@ -134,11 +135,13 @@ struct Configuration {
134 bool Demangle = true;135 bool Demangle = true;
135 bool DisableVerify;136 bool DisableVerify;
136 bool EhFrameHdr;137 bool EhFrameHdr;
138 bool EmitLLVM;
137 bool EmitRelocs;139 bool EmitRelocs;
138 bool EnableNewDtags;140 bool EnableNewDtags;
139 bool ExecuteOnly;141 bool ExecuteOnly;
140 bool ExportDynamic;142 bool ExportDynamic;
141 bool FixCortexA53Errata843419;143 bool FixCortexA53Errata843419;
144 bool FormatBinary = false;
142 bool GcSections;145 bool GcSections;
143 bool GdbIndex;146 bool GdbIndex;
144 bool GnuHash = false;147 bool GnuHash = false;
...@@ -156,6 +159,7 @@ struct Configuration {...@@ -156,6 +159,7 @@ struct Configuration {
156 bool OFormatBinary;159 bool OFormatBinary;
157 bool Omagic;160 bool Omagic;
158 bool OptRemarksWithHotness;161 bool OptRemarksWithHotness;
162 bool PicThunk;
159 bool Pie;163 bool Pie;
160 bool PrintGcSections;164 bool PrintGcSections;
161 bool PrintIcfSections;165 bool PrintIcfSections;
...@@ -170,19 +174,24 @@ struct Configuration {...@@ -170,19 +174,24 @@ struct Configuration {
170 bool Trace;174 bool Trace;
171 bool ThinLTOEmitImportsFiles;175 bool ThinLTOEmitImportsFiles;
172 bool ThinLTOIndexOnly;176 bool ThinLTOIndexOnly;
177 bool TocOptimize;
173 bool UndefinedVersion;178 bool UndefinedVersion;
174 bool UseAndroidRelrTags = false;179 bool UseAndroidRelrTags = false;
175 bool WarnBackrefs;180 bool WarnBackrefs;
176 bool WarnCommon;181 bool WarnCommon;
182 bool WarnIfuncTextrel;
177 bool WarnMissingEntry;183 bool WarnMissingEntry;
178 bool WarnSymbolOrdering;184 bool WarnSymbolOrdering;
179 bool WriteAddends;185 bool WriteAddends;
180 bool ZCombreloc;186 bool ZCombreloc;
181 bool ZCopyreloc;187 bool ZCopyreloc;
182 bool ZExecstack;188 bool ZExecstack;
189 bool ZGlobal;
183 bool ZHazardplt;190 bool ZHazardplt;
184 bool ZInitfirst;191 bool ZInitfirst;
192 bool ZInterpose;
185 bool ZKeepTextSectionPrefix;193 bool ZKeepTextSectionPrefix;
194 bool ZNodefaultlib;
186 bool ZNodelete;195 bool ZNodelete;
187 bool ZNodlopen;196 bool ZNodlopen;
188 bool ZNow;197 bool ZNow;
...@@ -212,6 +221,7 @@ struct Configuration {...@@ -212,6 +221,7 @@ struct Configuration {
212 unsigned LTOO;221 unsigned LTOO;
213 unsigned Optimize;222 unsigned Optimize;
214 unsigned ThinLTOJobs;223 unsigned ThinLTOJobs;
224 int32_t SplitStackAdjustSize;
215225
216 // The following config options do not directly correspond to any226 // The following config options do not directly correspond to any
217 // particualr command line options.227 // particualr command line options.
deps/lld/ELF/DWARF.cpp created+109
...@@ -0,0 +1,109 @@
1//===- DWARF.cpp ----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The -gdb-index option instructs the linker to emit a .gdb_index section.
11// The section contains information to make gdb startup faster.
12// The format of the section is described at
13// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html.
14//
15//===----------------------------------------------------------------------===//
16
17#include "DWARF.h"
18#include "Symbols.h"
19#include "Target.h"
20#include "lld/Common/Memory.h"
21#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
22#include "llvm/Object/ELFObjectFile.h"
23
24using namespace llvm;
25using namespace llvm::object;
26using namespace lld;
27using namespace lld::elf;
28
29template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) {
30 for (InputSectionBase *Sec : Obj->getSections()) {
31 if (!Sec)
32 continue;
33
34 if (LLDDWARFSection *M =
35 StringSwitch<LLDDWARFSection *>(Sec->Name)
36 .Case(".debug_addr", &AddrSection)
37 .Case(".debug_gnu_pubnames", &GnuPubNamesSection)
38 .Case(".debug_gnu_pubtypes", &GnuPubTypesSection)
39 .Case(".debug_info", &InfoSection)
40 .Case(".debug_ranges", &RangeSection)
41 .Case(".debug_rnglists", &RngListsSection)
42 .Case(".debug_line", &LineSection)
43 .Default(nullptr)) {
44 M->Data = toStringRef(Sec->data());
45 M->Sec = Sec;
46 continue;
47 }
48
49 if (Sec->Name == ".debug_abbrev")
50 AbbrevSection = toStringRef(Sec->data());
51 else if (Sec->Name == ".debug_str")
52 StrSection = toStringRef(Sec->data());
53 else if (Sec->Name == ".debug_line_str")
54 LineStringSection = toStringRef(Sec->data());
55 }
56}
57
58// Find if there is a relocation at Pos in Sec. The code is a bit
59// more complicated than usual because we need to pass a section index
60// to llvm since it has no idea about InputSection.
61template <class ELFT>
62template <class RelTy>
63Optional<RelocAddrEntry>
64LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos,
65 ArrayRef<RelTy> Rels) const {
66 auto It = std::lower_bound(
67 Rels.begin(), Rels.end(), Pos,
68 [](const RelTy &A, uint64_t B) { return A.r_offset < B; });
69 if (It == Rels.end() || It->r_offset != Pos)
70 return None;
71 const RelTy &Rel = *It;
72
73 const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
74 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
75 const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex];
76 uint32_t SecIndex = File->getSectionIndex(Sym);
77
78 // Broken debug info can point to a non-Defined symbol.
79 auto *DR = dyn_cast<Defined>(&File->getRelocTargetSym(Rel));
80 if (!DR) {
81 RelType Type = Rel.getType(Config->IsMips64EL);
82 if (Type != Target->NoneRel)
83 error(toString(File) + ": relocation " + lld::toString(Type) + " at 0x" +
84 llvm::utohexstr(Rel.r_offset) + " has unsupported target");
85 return None;
86 }
87 uint64_t Val = DR->Value + getAddend<ELFT>(Rel);
88
89 // FIXME: We should be consistent about always adding the file
90 // offset or not.
91 if (DR->Section->Flags & ELF::SHF_ALLOC)
92 Val += cast<InputSection>(DR->Section)->getOffsetInFile();
93
94 return RelocAddrEntry{SecIndex, Val};
95}
96
97template <class ELFT>
98Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &S,
99 uint64_t Pos) const {
100 auto &Sec = static_cast<const LLDDWARFSection &>(S);
101 if (Sec.Sec->AreRelocsRela)
102 return findAux(*Sec.Sec, Pos, Sec.Sec->template relas<ELFT>());
103 return findAux(*Sec.Sec, Pos, Sec.Sec->template rels<ELFT>());
104}
105
106template class elf::LLDDwarfObj<ELF32LE>;
107template class elf::LLDDwarfObj<ELF32BE>;
108template class elf::LLDDwarfObj<ELF64LE>;
109template class elf::LLDDwarfObj<ELF64BE>;
deps/lld/ELF/DWARF.h created+93
...@@ -0,0 +1,93 @@
1//===- DWARF.h -----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===-------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_DWARF_H
11#define LLD_ELF_DWARF_H
12
13#include "InputFiles.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/DebugInfo/DWARF/DWARFContext.h"
16#include "llvm/Object/ELF.h"
17
18namespace lld {
19namespace elf {
20
21class InputSection;
22
23struct LLDDWARFSection final : public llvm::DWARFSection {
24 InputSectionBase *Sec = nullptr;
25};
26
27template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject {
28public:
29 explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
30
31 void forEachInfoSections(
32 llvm::function_ref<void(const llvm::DWARFSection &)> F) const override {
33 F(InfoSection);
34 }
35
36 const llvm::DWARFSection &getRangeSection() const override {
37 return RangeSection;
38 }
39
40 const llvm::DWARFSection &getRnglistsSection() const override {
41 return RngListsSection;
42 }
43
44 const llvm::DWARFSection &getLineSection() const override {
45 return LineSection;
46 }
47
48 const llvm::DWARFSection &getAddrSection() const override {
49 return AddrSection;
50 }
51
52 const llvm::DWARFSection &getGnuPubNamesSection() const override {
53 return GnuPubNamesSection;
54 }
55
56 const llvm::DWARFSection &getGnuPubTypesSection() const override {
57 return GnuPubTypesSection;
58 }
59
60 StringRef getFileName() const override { return ""; }
61 StringRef getAbbrevSection() const override { return AbbrevSection; }
62 StringRef getStringSection() const override { return StrSection; }
63 StringRef getLineStringSection() const override { return LineStringSection; }
64
65 bool isLittleEndian() const override {
66 return ELFT::TargetEndianness == llvm::support::little;
67 }
68
69 llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
70 uint64_t Pos) const override;
71
72private:
73 template <class RelTy>
74 llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &Sec,
75 uint64_t Pos,
76 ArrayRef<RelTy> Rels) const;
77
78 LLDDWARFSection GnuPubNamesSection;
79 LLDDWARFSection GnuPubTypesSection;
80 LLDDWARFSection InfoSection;
81 LLDDWARFSection RangeSection;
82 LLDDWARFSection RngListsSection;
83 LLDDWARFSection LineSection;
84 LLDDWARFSection AddrSection;
85 StringRef AbbrevSection;
86 StringRef StrSection;
87 StringRef LineStringSection;
88};
89
90} // namespace elf
91} // namespace lld
92
93#endif
deps/lld/ELF/Driver.cpp+255-124
...@@ -63,6 +63,7 @@ using namespace llvm;...@@ -63,6 +63,7 @@ using namespace llvm;
63using namespace llvm::ELF;63using namespace llvm::ELF;
64using namespace llvm::object;64using namespace llvm::object;
65using namespace llvm::sys;65using namespace llvm::sys;
66using namespace llvm::support;
6667
67using namespace lld;68using namespace lld;
68using namespace lld::elf;69using namespace lld::elf;
...@@ -74,7 +75,7 @@ static void setConfigs(opt::InputArgList &Args);...@@ -74,7 +75,7 @@ static void setConfigs(opt::InputArgList &Args);
7475
75bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,76bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
76 raw_ostream &Error) {77 raw_ostream &Error) {
77 errorHandler().LogName = sys::path::filename(Args[0]);78 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
78 errorHandler().ErrorLimitExceededMsg =79 errorHandler().ErrorLimitExceededMsg =
79 "too many errors emitted, stopping now (use "80 "too many errors emitted, stopping now (use "
80 "-error-limit=0 to see all errors)";81 "-error-limit=0 to see all errors)";
...@@ -84,7 +85,6 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,...@@ -84,7 +85,6 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
8485
85 InputSections.clear();86 InputSections.clear();
86 OutputSections.clear();87 OutputSections.clear();
87 Tar = nullptr;
88 BinaryFiles.clear();88 BinaryFiles.clear();
89 BitcodeFiles.clear();89 BitcodeFiles.clear();
90 ObjectFiles.clear();90 ObjectFiles.clear();
...@@ -94,6 +94,10 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,...@@ -94,6 +94,10 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
94 Driver = make<LinkerDriver>();94 Driver = make<LinkerDriver>();
95 Script = make<LinkerScript>();95 Script = make<LinkerScript>();
96 Symtab = make<SymbolTable>();96 Symtab = make<SymbolTable>();
97
98 Tar = nullptr;
99 memset(&In, 0, sizeof(In));
100
97 Config->ProgName = Args[0];101 Config->ProgName = Args[0];
98102
99 Driver->main(Args);103 Driver->main(Args);
...@@ -125,9 +129,11 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {...@@ -125,9 +129,11 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
125 .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})129 .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
126 .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})130 .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
127 .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})131 .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
132 .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
128 .Case("elf32ppc", {ELF32BEKind, EM_PPC})133 .Case("elf32ppc", {ELF32BEKind, EM_PPC})
129 .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})134 .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
130 .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})135 .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
136 .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
131 .Case("elf64ppc", {ELF64BEKind, EM_PPC64})137 .Case("elf64ppc", {ELF64BEKind, EM_PPC64})
132 .Case("elf64lppc", {ELF64LEKind, EM_PPC64})138 .Case("elf64lppc", {ELF64LEKind, EM_PPC64})
133 .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})139 .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
...@@ -183,7 +189,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {...@@ -183,7 +189,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
183 return;189 return;
184 MemoryBufferRef MBRef = *Buffer;190 MemoryBufferRef MBRef = *Buffer;
185191
186 if (InBinary) {192 if (Config->FormatBinary) {
187 Files.push_back(make<BinaryFile>(MBRef));193 Files.push_back(make<BinaryFile>(MBRef));
188 return;194 return;
189 }195 }
...@@ -218,7 +224,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {...@@ -218,7 +224,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
218 return;224 return;
219 }225 }
220 case file_magic::elf_shared_object:226 case file_magic::elf_shared_object:
221 if (Config->Relocatable) {227 if (Config->Static || Config->Relocatable) {
222 error("attempted static link of dynamic object " + Path);228 error("attempted static link of dynamic object " + Path);
223 return;229 return;
224 }230 }
...@@ -269,14 +275,17 @@ static void initLLVM() {...@@ -269,14 +275,17 @@ static void initLLVM() {
269275
270// Some command line options or some combinations of them are not allowed.276// Some command line options or some combinations of them are not allowed.
271// This function checks for such errors.277// This function checks for such errors.
272static void checkOptions(opt::InputArgList &Args) {278static void checkOptions() {
273 // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup279 // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
274 // table which is a relatively new feature.280 // table which is a relatively new feature.
275 if (Config->EMachine == EM_MIPS && Config->GnuHash)281 if (Config->EMachine == EM_MIPS && Config->GnuHash)
276 error("the .gnu.hash section is not compatible with the MIPS target.");282 error("the .gnu.hash section is not compatible with the MIPS target");
277283
278 if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)284 if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)
279 error("--fix-cortex-a53-843419 is only supported on AArch64 targets.");285 error("--fix-cortex-a53-843419 is only supported on AArch64 targets");
286
287 if (Config->TocOptimize && Config->EMachine != EM_PPC64)
288 error("--toc-optimize is only supported on the PowerPC64 target");
280289
281 if (Config->Pie && Config->Shared)290 if (Config->Pie && Config->Shared)
282 error("-shared and -pie may not be used together");291 error("-shared and -pie may not be used together");
...@@ -336,12 +345,13 @@ static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,...@@ -336,12 +345,13 @@ static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
336 return Default;345 return Default;
337}346}
338347
339static bool isKnown(StringRef S) {348static bool isKnownZFlag(StringRef S) {
340 return S == "combreloc" || S == "copyreloc" || S == "defs" ||349 return S == "combreloc" || S == "copyreloc" || S == "defs" ||
341 S == "execstack" || S == "hazardplt" || S == "initfirst" ||350 S == "execstack" || S == "global" || S == "hazardplt" ||
351 S == "initfirst" || S == "interpose" ||
342 S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||352 S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
343 S == "nocombreloc" || S == "nocopyreloc" || S == "nodelete" ||353 S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
344 S == "nodlopen" || S == "noexecstack" ||354 S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
345 S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||355 S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
346 S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||356 S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
347 S == "rodynamic" || S == "text" || S == "wxneeded" ||357 S == "rodynamic" || S == "text" || S == "wxneeded" ||
...@@ -351,7 +361,7 @@ static bool isKnown(StringRef S) {...@@ -351,7 +361,7 @@ static bool isKnown(StringRef S) {
351// Report an error for an unknown -z option.361// Report an error for an unknown -z option.
352static void checkZOptions(opt::InputArgList &Args) {362static void checkZOptions(opt::InputArgList &Args) {
353 for (auto *Arg : Args.filtered(OPT_z))363 for (auto *Arg : Args.filtered(OPT_z))
354 if (!isKnown(Arg->getValue()))364 if (!isKnownZFlag(Arg->getValue()))
355 error("unknown -z value: " + StringRef(Arg->getValue()));365 error("unknown -z value: " + StringRef(Arg->getValue()));
356}366}
357367
...@@ -386,31 +396,30 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {...@@ -386,31 +396,30 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
386 if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))396 if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
387 message(getLLDVersion() + " (compatible with GNU linkers)");397 message(getLLDVersion() + " (compatible with GNU linkers)");
388398
389 // The behavior of -v or --version is a bit strange, but this is
390 // needed for compatibility with GNU linkers.
391 if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT))
392 return;
393 if (Args.hasArg(OPT_version))
394 return;
395
396 if (const char *Path = getReproduceOption(Args)) {399 if (const char *Path = getReproduceOption(Args)) {
397 // Note that --reproduce is a debug option so you can ignore it400 // Note that --reproduce is a debug option so you can ignore it
398 // if you are trying to understand the whole picture of the code.401 // if you are trying to understand the whole picture of the code.
399 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =402 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
400 TarWriter::create(Path, path::stem(Path));403 TarWriter::create(Path, path::stem(Path));
401 if (ErrOrWriter) {404 if (ErrOrWriter) {
402 Tar = ErrOrWriter->get();405 Tar = std::move(*ErrOrWriter);
403 Tar->append("response.txt", createResponseFile(Args));406 Tar->append("response.txt", createResponseFile(Args));
404 Tar->append("version.txt", getLLDVersion() + "\n");407 Tar->append("version.txt", getLLDVersion() + "\n");
405 make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
406 } else {408 } else {
407 error(Twine("--reproduce: failed to open ") + Path + ": " +409 error("--reproduce: " + toString(ErrOrWriter.takeError()));
408 toString(ErrOrWriter.takeError()));
409 }410 }
410 }411 }
411412
412 readConfigs(Args);413 readConfigs(Args);
413 checkZOptions(Args);414 checkZOptions(Args);
415
416 // The behavior of -v or --version is a bit strange, but this is
417 // needed for compatibility with GNU linkers.
418 if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT))
419 return;
420 if (Args.hasArg(OPT_version))
421 return;
422
414 initLLVM();423 initLLVM();
415 createFiles(Args);424 createFiles(Args);
416 if (errorCount())425 if (errorCount())
...@@ -418,7 +427,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {...@@ -418,7 +427,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
418427
419 inferMachineType();428 inferMachineType();
420 setConfigs(Args);429 setConfigs(Args);
421 checkOptions(Args);430 checkOptions();
422 if (errorCount())431 if (errorCount())
423 return;432 return;
424433
...@@ -448,9 +457,6 @@ static std::string getRpath(opt::InputArgList &Args) {...@@ -448,9 +457,6 @@ static std::string getRpath(opt::InputArgList &Args) {
448// Determines what we should do if there are remaining unresolved457// Determines what we should do if there are remaining unresolved
449// symbols after the name resolution.458// symbols after the name resolution.
450static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {459static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
451 if (Args.hasArg(OPT_relocatable))
452 return UnresolvedPolicy::IgnoreAll;
453
454 UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,460 UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
455 OPT_warn_unresolved_symbols, true)461 OPT_warn_unresolved_symbols, true)
456 ? UnresolvedPolicy::ReportError462 ? UnresolvedPolicy::ReportError
...@@ -497,14 +503,11 @@ static Target2Policy getTarget2(opt::InputArgList &Args) {...@@ -497,14 +503,11 @@ static Target2Policy getTarget2(opt::InputArgList &Args) {
497}503}
498504
499static bool isOutputFormatBinary(opt::InputArgList &Args) {505static bool isOutputFormatBinary(opt::InputArgList &Args) {
500 if (auto *Arg = Args.getLastArg(OPT_oformat)) {506 StringRef S = Args.getLastArgValue(OPT_oformat, "elf");
501 StringRef S = Arg->getValue();507 if (S == "binary")
502 if (S == "binary")508 return true;
503 return true;509 if (!S.startswith("elf"))
504 if (S.startswith("elf"))
505 return false;
506 error("unknown --oformat value: " + S);510 error("unknown --oformat value: " + S);
507 }
508 return false;511 return false;
509}512}
510513
...@@ -645,38 +648,56 @@ static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {...@@ -645,38 +648,56 @@ static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {
645648
646static void readCallGraph(MemoryBufferRef MB) {649static void readCallGraph(MemoryBufferRef MB) {
647 // Build a map from symbol name to section650 // Build a map from symbol name to section
648 DenseMap<StringRef, const Symbol *> SymbolNameToSymbol;651 DenseMap<StringRef, Symbol *> Map;
649 for (InputFile *File : ObjectFiles)652 for (InputFile *File : ObjectFiles)
650 for (Symbol *Sym : File->getSymbols())653 for (Symbol *Sym : File->getSymbols())
651 SymbolNameToSymbol[Sym->getName()] = Sym;654 Map[Sym->getName()] = Sym;
655
656 auto FindSection = [&](StringRef Name) -> InputSectionBase * {
657 Symbol *Sym = Map.lookup(Name);
658 if (!Sym) {
659 if (Config->WarnSymbolOrdering)
660 warn(MB.getBufferIdentifier() + ": no such symbol: " + Name);
661 return nullptr;
662 }
663 maybeWarnUnorderableSymbol(Sym);
664
665 if (Defined *DR = dyn_cast_or_null<Defined>(Sym))
666 return dyn_cast_or_null<InputSectionBase>(DR->Section);
667 return nullptr;
668 };
652669
653 for (StringRef L : args::getLines(MB)) {670 for (StringRef Line : args::getLines(MB)) {
654 SmallVector<StringRef, 3> Fields;671 SmallVector<StringRef, 3> Fields;
655 L.split(Fields, ' ');672 Line.split(Fields, ' ');
656 uint64_t Count;673 uint64_t Count;
657 if (Fields.size() != 3 || !to_integer(Fields[2], Count))674
658 fatal(MB.getBufferIdentifier() + ": parse error");675 if (Fields.size() != 3 || !to_integer(Fields[2], Count)) {
659 const Symbol *FromSym = SymbolNameToSymbol.lookup(Fields[0]);676 error(MB.getBufferIdentifier() + ": parse error");
660 const Symbol *ToSym = SymbolNameToSymbol.lookup(Fields[1]);677 return;
661 if (Config->WarnSymbolOrdering) {678 }
662 if (!FromSym)679
663 warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[0]);680 if (InputSectionBase *From = FindSection(Fields[0]))
664 if (!ToSym)681 if (InputSectionBase *To = FindSection(Fields[1]))
665 warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[1]);682 Config->CallGraphProfile[std::make_pair(From, To)] += Count;
683 }
684}
685
686template <class ELFT> static void readCallGraphsFromObjectFiles() {
687 for (auto File : ObjectFiles) {
688 auto *Obj = cast<ObjFile<ELFT>>(File);
689
690 for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) {
691 auto *FromSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_from));
692 auto *ToSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_to));
693 if (!FromSym || !ToSym)
694 continue;
695
696 auto *From = dyn_cast_or_null<InputSectionBase>(FromSym->Section);
697 auto *To = dyn_cast_or_null<InputSectionBase>(ToSym->Section);
698 if (From && To)
699 Config->CallGraphProfile[{From, To}] += CGPE.cgp_weight;
666 }700 }
667 if (!FromSym || !ToSym || Count == 0)
668 continue;
669 warnUnorderableSymbol(FromSym);
670 warnUnorderableSymbol(ToSym);
671 const Defined *FromSymD = dyn_cast<Defined>(FromSym);
672 const Defined *ToSymD = dyn_cast<Defined>(ToSym);
673 if (!FromSymD || !ToSymD)
674 continue;
675 const auto *FromSB = dyn_cast_or_null<InputSectionBase>(FromSymD->Section);
676 const auto *ToSB = dyn_cast_or_null<InputSectionBase>(ToSymD->Section);
677 if (!FromSB || !ToSB)
678 continue;
679 Config->CallGraphProfile[std::make_pair(FromSB, ToSB)] += Count;
680 }701 }
681}702}
682703
...@@ -753,7 +774,10 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {...@@ -753,7 +774,10 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
753 Config->DynamicLinker = getDynamicLinker(Args);774 Config->DynamicLinker = getDynamicLinker(Args);
754 Config->EhFrameHdr =775 Config->EhFrameHdr =
755 Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);776 Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
777 Config->EmitLLVM = Args.hasArg(OPT_plugin_opt_emit_llvm, false);
756 Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);778 Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
779 Config->CallGraphProfileSort = Args.hasFlag(
780 OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
757 Config->EnableNewDtags =781 Config->EnableNewDtags =
758 Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);782 Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
759 Config->Entry = Args.getLastArgValue(OPT_entry);783 Config->Entry = Args.getLastArgValue(OPT_entry);
...@@ -808,6 +832,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {...@@ -808,6 +832,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
808 Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);832 Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
809 Config->SoName = Args.getLastArgValue(OPT_soname);833 Config->SoName = Args.getLastArgValue(OPT_soname);
810 Config->SortSection = getSortSection(Args);834 Config->SortSection = getSortSection(Args);
835 Config->SplitStackAdjustSize = args::getInteger(Args, OPT_split_stack_adjust_size, 16384);
811 Config->Strip = getStrip(Args);836 Config->Strip = getStrip(Args);
812 Config->Sysroot = Args.getLastArgValue(OPT_sysroot);837 Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
813 Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);838 Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
...@@ -837,15 +862,20 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {...@@ -837,15 +862,20 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
837 Config->WarnBackrefs =862 Config->WarnBackrefs =
838 Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);863 Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
839 Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);864 Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
865 Config->WarnIfuncTextrel =
866 Args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
840 Config->WarnSymbolOrdering =867 Config->WarnSymbolOrdering =
841 Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);868 Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
842 Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);869 Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
843 Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);870 Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
844 Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);871 Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
872 Config->ZGlobal = hasZOption(Args, "global");
845 Config->ZHazardplt = hasZOption(Args, "hazardplt");873 Config->ZHazardplt = hasZOption(Args, "hazardplt");
846 Config->ZInitfirst = hasZOption(Args, "initfirst");874 Config->ZInitfirst = hasZOption(Args, "initfirst");
875 Config->ZInterpose = hasZOption(Args, "interpose");
847 Config->ZKeepTextSectionPrefix = getZFlag(876 Config->ZKeepTextSectionPrefix = getZFlag(
848 Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);877 Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
878 Config->ZNodefaultlib = hasZOption(Args, "nodefaultlib");
849 Config->ZNodelete = hasZOption(Args, "nodelete");879 Config->ZNodelete = hasZOption(Args, "nodelete");
850 Config->ZNodlopen = hasZOption(Args, "nodlopen");880 Config->ZNodlopen = hasZOption(Args, "nodlopen");
851 Config->ZNow = getZFlag(Args, "now", "lazy", false);881 Config->ZNow = getZFlag(Args, "now", "lazy", false);
...@@ -876,6 +906,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {...@@ -876,6 +906,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
876 if (Config->ThinLTOJobs == 0)906 if (Config->ThinLTOJobs == 0)
877 error("--thinlto-jobs: number of threads must be > 0");907 error("--thinlto-jobs: number of threads must be > 0");
878908
909 if (Config->SplitStackAdjustSize < 0)
910 error("--split-stack-adjust-size: size must be >= 0");
911
879 // Parse ELF{32,64}{LE,BE} and CPU type.912 // Parse ELF{32,64}{LE,BE} and CPU type.
880 if (auto *Arg = Args.getLastArg(OPT_m)) {913 if (auto *Arg = Args.getLastArg(OPT_m)) {
881 StringRef S = Arg->getValue();914 StringRef S = Arg->getValue();
...@@ -964,22 +997,18 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {...@@ -964,22 +997,18 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
964// This function initialize such members. See Config.h for the details997// This function initialize such members. See Config.h for the details
965// of these values.998// of these values.
966static void setConfigs(opt::InputArgList &Args) {999static void setConfigs(opt::InputArgList &Args) {
967 ELFKind Kind = Config->EKind;1000 ELFKind K = Config->EKind;
968 uint16_t Machine = Config->EMachine;1001 uint16_t M = Config->EMachine;
9691002
970 Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);1003 Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
971 Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind);1004 Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind);
972 Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind);1005 Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind);
973 Config->Endianness =1006 Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
974 Config->IsLE ? support::endianness::little : support::endianness::big;1007 Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
975 Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS);
976 Config->Pic = Config->Pie || Config->Shared;1008 Config->Pic = Config->Pie || Config->Shared;
1009 Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
977 Config->Wordsize = Config->Is64 ? 8 : 4;1010 Config->Wordsize = Config->Is64 ? 8 : 4;
9781011
979 // There is an ILP32 ABI for x86-64, although it's not very popular.
980 // It is called the x32 ABI.
981 bool IsX32 = (Kind == ELF32LEKind && Machine == EM_X86_64);
982
983 // ELF defines two different ways to store relocation addends as shown below:1012 // ELF defines two different ways to store relocation addends as shown below:
984 //1013 //
985 // Rel: Addends are stored to the location where relocations are applied.1014 // Rel: Addends are stored to the location where relocations are applied.
...@@ -993,8 +1022,9 @@ static void setConfigs(opt::InputArgList &Args) {...@@ -993,8 +1022,9 @@ static void setConfigs(opt::InputArgList &Args) {
993 // You cannot choose which one, Rel or Rela, you want to use. Instead each1022 // You cannot choose which one, Rel or Rela, you want to use. Instead each
994 // ABI defines which one you need to use. The following expression expresses1023 // ABI defines which one you need to use. The following expression expresses
995 // that.1024 // that.
996 Config->IsRela =1025 Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
997 (Config->Is64 || IsX32 || Machine == EM_PPC) && Machine != EM_MIPS;1026 M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
1027 M == EM_X86_64;
9981028
999 // If the output uses REL relocations we must store the dynamic relocation1029 // If the output uses REL relocations we must store the dynamic relocation
1000 // addends to the output sections. We also store addends for RELA relocations1030 // addends to the output sections. We also store addends for RELA relocations
...@@ -1004,10 +1034,13 @@ static void setConfigs(opt::InputArgList &Args) {...@@ -1004,10 +1034,13 @@ static void setConfigs(opt::InputArgList &Args) {
1004 Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,1034 Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
1005 OPT_no_apply_dynamic_relocs, false) ||1035 OPT_no_apply_dynamic_relocs, false) ||
1006 !Config->IsRela;1036 !Config->IsRela;
1037
1038 Config->TocOptimize =
1039 Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
1007}1040}
10081041
1009// Returns a value of "-format" option.1042// Returns a value of "-format" option.
1010static bool getBinaryOption(StringRef S) {1043static bool isFormatBinary(StringRef S) {
1011 if (S == "binary")1044 if (S == "binary")
1012 return true;1045 return true;
1013 if (S == "elf" || S == "default")1046 if (S == "elf" || S == "default")
...@@ -1034,7 +1067,10 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {...@@ -1034,7 +1067,10 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
1034 StringRef From;1067 StringRef From;
1035 StringRef To;1068 StringRef To;
1036 std::tie(From, To) = StringRef(Arg->getValue()).split('=');1069 std::tie(From, To) = StringRef(Arg->getValue()).split('=');
1037 readDefsym(From, MemoryBufferRef(To, "-defsym"));1070 if (From.empty() || To.empty())
1071 error("-defsym: syntax error: " + StringRef(Arg->getValue()));
1072 else
1073 readDefsym(From, MemoryBufferRef(To, "-defsym"));
1038 break;1074 break;
1039 }1075 }
1040 case OPT_script:1076 case OPT_script:
...@@ -1049,7 +1085,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {...@@ -1049,7 +1085,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
1049 Config->AsNeeded = true;1085 Config->AsNeeded = true;
1050 break;1086 break;
1051 case OPT_format:1087 case OPT_format:
1052 InBinary = getBinaryOption(Arg->getValue());1088 Config->FormatBinary = isFormatBinary(Arg->getValue());
1053 break;1089 break;
1054 case OPT_no_as_needed:1090 case OPT_no_as_needed:
1055 Config->AsNeeded = false;1091 Config->AsNeeded = false;
...@@ -1220,33 +1256,34 @@ template <class ELFT> static void handleUndefined(StringRef Name) {...@@ -1220,33 +1256,34 @@ template <class ELFT> static void handleUndefined(StringRef Name) {
1220 Symtab->fetchLazy<ELFT>(Sym);1256 Symtab->fetchLazy<ELFT>(Sym);
1221}1257}
12221258
1223template <class ELFT> static bool shouldDemote(Symbol &Sym) {1259template <class ELFT> static void handleLibcall(StringRef Name) {
1224 // If all references to a DSO happen to be weak, the DSO is not added to1260 Symbol *Sym = Symtab->find(Name);
1225 // DT_NEEDED. If that happens, we need to eliminate shared symbols created1261 if (!Sym || !Sym->isLazy())
1226 // from the DSO. Otherwise, they become dangling references that point to a1262 return;
1227 // non-existent DSO.1263
1228 if (auto *S = dyn_cast<SharedSymbol>(&Sym))1264 MemoryBufferRef MB;
1229 return !S->getFile<ELFT>().IsNeeded;1265 if (auto *LO = dyn_cast<LazyObject>(Sym))
12301266 MB = LO->File->MB;
1231 // We are done processing archives, so lazy symbols that were used but not1267 else
1232 // found can be converted to undefined. We could also just delete the other1268 MB = cast<LazyArchive>(Sym)->getMemberBuffer();
1233 // lazy symbols, but that seems to be more work than it is worth.1269
1234 return Sym.isLazy() && Sym.IsUsedInRegularObj;1270 if (isBitcode(MB))
1271 Symtab->fetchLazy<ELFT>(Sym);
1235}1272}
12361273
1237// Some files, such as .so or files between -{start,end}-lib may be removed1274// If all references to a DSO happen to be weak, the DSO is not added
1238// after their symbols are added to the symbol table. If that happens, we1275// to DT_NEEDED. If that happens, we need to eliminate shared symbols
1239// need to remove symbols that refer files that no longer exist, so that1276// created from the DSO. Otherwise, they become dangling references
1240// they won't appear in the symbol table of the output file.1277// that point to a non-existent DSO.
1241//1278template <class ELFT> static void demoteSharedSymbols() {
1242// We remove symbols by demoting them to undefined symbol.
1243template <class ELFT> static void demoteSymbols() {
1244 for (Symbol *Sym : Symtab->getSymbols()) {1279 for (Symbol *Sym : Symtab->getSymbols()) {
1245 if (shouldDemote<ELFT>(*Sym)) {1280 if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
1246 bool Used = Sym->Used;1281 if (!S->getFile<ELFT>().IsNeeded) {
1247 replaceSymbol<Undefined>(Sym, nullptr, Sym->getName(), Sym->Binding,1282 bool Used = S->Used;
1248 Sym->StOther, Sym->Type);1283 replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
1249 Sym->Used = Used;1284 S->Type);
1285 S->Used = Used;
1286 }
1250 }1287 }
1251 }1288 }
1252}1289}
...@@ -1315,6 +1352,85 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {...@@ -1315,6 +1352,85 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
1315 }1352 }
1316}1353}
13171354
1355template <class ELFT> static Symbol *addUndefined(StringRef Name) {
1356 return Symtab->addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, 0, false,
1357 nullptr);
1358}
1359
1360// The --wrap option is a feature to rename symbols so that you can write
1361// wrappers for existing functions. If you pass `-wrap=foo`, all
1362// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
1363// expected to write `wrap_foo` function as a wrapper). The original
1364// symbol becomes accessible as `real_foo`, so you can call that from your
1365// wrapper.
1366//
1367// This data structure is instantiated for each -wrap option.
1368struct WrappedSymbol {
1369 Symbol *Sym;
1370 Symbol *Real;
1371 Symbol *Wrap;
1372};
1373
1374// Handles -wrap option.
1375//
1376// This function instantiates wrapper symbols. At this point, they seem
1377// like they are not being used at all, so we explicitly set some flags so
1378// that LTO won't eliminate them.
1379template <class ELFT>
1380static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
1381 std::vector<WrappedSymbol> V;
1382 DenseSet<StringRef> Seen;
1383
1384 for (auto *Arg : Args.filtered(OPT_wrap)) {
1385 StringRef Name = Arg->getValue();
1386 if (!Seen.insert(Name).second)
1387 continue;
1388
1389 Symbol *Sym = Symtab->find(Name);
1390 if (!Sym)
1391 continue;
1392
1393 Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
1394 Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
1395 V.push_back({Sym, Real, Wrap});
1396
1397 // We want to tell LTO not to inline symbols to be overwritten
1398 // because LTO doesn't know the final symbol contents after renaming.
1399 Real->CanInline = false;
1400 Sym->CanInline = false;
1401
1402 // Tell LTO not to eliminate these symbols.
1403 Sym->IsUsedInRegularObj = true;
1404 Wrap->IsUsedInRegularObj = true;
1405 }
1406 return V;
1407}
1408
1409// Do renaming for -wrap by updating pointers to symbols.
1410//
1411// When this function is executed, only InputFiles and symbol table
1412// contain pointers to symbol objects. We visit them to replace pointers,
1413// so that wrapped symbols are swapped as instructed by the command line.
1414template <class ELFT> static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) {
1415 DenseMap<Symbol *, Symbol *> Map;
1416 for (const WrappedSymbol &W : Wrapped) {
1417 Map[W.Sym] = W.Wrap;
1418 Map[W.Real] = W.Sym;
1419 }
1420
1421 // Update pointers in input files.
1422 parallelForEach(ObjectFiles, [&](InputFile *File) {
1423 std::vector<Symbol *> &Syms = File->getMutableSymbols();
1424 for (size_t I = 0, E = Syms.size(); I != E; ++I)
1425 if (Symbol *S = Map.lookup(Syms[I]))
1426 Syms[I] = S;
1427 });
1428
1429 // Update pointers in the symbol table.
1430 for (const WrappedSymbol &W : Wrapped)
1431 Symtab->wrap(W.Sym, W.Real, W.Wrap);
1432}
1433
1318static const char *LibcallRoutineNames[] = {1434static const char *LibcallRoutineNames[] = {
1319#define HANDLE_LIBCALL(code, name) name,1435#define HANDLE_LIBCALL(code, name) name,
1320#include "llvm/IR/RuntimeLibcalls.def"1436#include "llvm/IR/RuntimeLibcalls.def"
...@@ -1325,6 +1441,8 @@ static const char *LibcallRoutineNames[] = {...@@ -1325,6 +1441,8 @@ static const char *LibcallRoutineNames[] = {
1325// all linker scripts have already been parsed.1441// all linker scripts have already been parsed.
1326template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {1442template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1327 Target = getTarget();1443 Target = getTarget();
1444 InX<ELFT>::VerSym = nullptr;
1445 InX<ELFT>::VerNeed = nullptr;
13281446
1329 Config->MaxPageSize = getMaxPageSize(Args);1447 Config->MaxPageSize = getMaxPageSize(Args);
1330 Config->ImageBase = getImageBase(Args);1448 Config->ImageBase = getImageBase(Args);
...@@ -1380,8 +1498,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1380,8 +1498,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
13801498
1381 // Some symbols (such as __ehdr_start) are defined lazily only when there1499 // Some symbols (such as __ehdr_start) are defined lazily only when there
1382 // are undefined symbols for them, so we add these to trigger that logic.1500 // are undefined symbols for them, so we add these to trigger that logic.
1383 for (StringRef Sym : Script->ReferencedSymbols)1501 for (StringRef Name : Script->ReferencedSymbols)
1384 Symtab->addUndefined<ELFT>(Sym);1502 addUndefined<ELFT>(Name);
13851503
1386 // Handle the `--undefined <sym>` options.1504 // Handle the `--undefined <sym>` options.
1387 for (StringRef S : Config->Undefined)1505 for (StringRef S : Config->Undefined)
...@@ -1396,11 +1514,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1396,11 +1514,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1396 // in a bitcode file in an archive member, we need to arrange to use LTO to1514 // in a bitcode file in an archive member, we need to arrange to use LTO to
1397 // compile those archive members by adding them to the link beforehand.1515 // compile those archive members by adding them to the link beforehand.
1398 //1516 //
1399 // With this the symbol table should be complete. After this, no new names1517 // However, adding all libcall symbols to the link can have undesired
1400 // except a few linker-synthesized ones will be added to the symbol table.1518 // consequences. For example, the libgcc implementation of
1519 // __sync_val_compare_and_swap_8 on 32-bit ARM pulls in an .init_array entry
1520 // that aborts the program if the Linux kernel does not support 64-bit
1521 // atomics, which would prevent the program from running even if it does not
1522 // use 64-bit atomics.
1523 //
1524 // Therefore, we only add libcall symbols to the link before LTO if we have
1525 // to, i.e. if the symbol's definition is in bitcode. Any other required
1526 // libcall symbols will be added to the link after LTO when we add the LTO
1527 // object file to the link.
1401 if (!BitcodeFiles.empty())1528 if (!BitcodeFiles.empty())
1402 for (const char *S : LibcallRoutineNames)1529 for (const char *S : LibcallRoutineNames)
1403 handleUndefined<ELFT>(S);1530 handleLibcall<ELFT>(S);
14041531
1405 // Return if there were name resolution errors.1532 // Return if there were name resolution errors.
1406 if (errorCount())1533 if (errorCount())
...@@ -1424,6 +1551,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1424,6 +1551,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1424 Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);1551 Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
1425 Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);1552 Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
14261553
1554 // Create wrapped symbols for -wrap option.
1555 std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
1556
1427 // We need to create some reserved symbols such as _end. Create them.1557 // We need to create some reserved symbols such as _end. Create them.
1428 if (!Config->Relocatable)1558 if (!Config->Relocatable)
1429 addReservedSymbols();1559 addReservedSymbols();
...@@ -1436,12 +1566,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1436,12 +1566,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1436 if (!Config->Relocatable)1566 if (!Config->Relocatable)
1437 Symtab->scanVersionScript();1567 Symtab->scanVersionScript();
14381568
1439 // Create wrapped symbols for -wrap option.
1440 for (auto *Arg : Args.filtered(OPT_wrap))
1441 Symtab->addSymbolWrap<ELFT>(Arg->getValue());
1442
1443 // Do link-time optimization if given files are LLVM bitcode files.1569 // Do link-time optimization if given files are LLVM bitcode files.
1444 // This compiles bitcode files into real object files.1570 // This compiles bitcode files into real object files.
1571 //
1572 // With this the symbol table should be complete. After this, no new names
1573 // except a few linker-synthesized ones will be added to the symbol table.
1445 Symtab->addCombinedLTOObject<ELFT>();1574 Symtab->addCombinedLTOObject<ELFT>();
1446 if (errorCount())1575 if (errorCount())
1447 return;1576 return;
...@@ -1452,8 +1581,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1452,8 +1581,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1452 if (Config->ThinLTOIndexOnly)1581 if (Config->ThinLTOIndexOnly)
1453 return;1582 return;
14541583
1584 // Likewise, --plugin-opt=emit-llvm is an option to make LTO create
1585 // an output file in bitcode and exit, so that you can just get a
1586 // combined bitcode file.
1587 if (Config->EmitLLVM)
1588 return;
1589
1455 // Apply symbol renames for -wrap.1590 // Apply symbol renames for -wrap.
1456 Symtab->applySymbolWrap();1591 if (!Wrapped.empty())
1592 wrapSymbols<ELFT>(Wrapped);
14571593
1458 // Now that we have a complete list of input files.1594 // Now that we have a complete list of input files.
1459 // Beyond this point, no new files are added.1595 // Beyond this point, no new files are added.
...@@ -1481,27 +1617,19 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1481,27 +1617,19 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1481 // supports them.1617 // supports them.
1482 if (Config->ARMHasBlx == false)1618 if (Config->ARMHasBlx == false)
1483 warn("lld uses blx instruction, no object with architecture supporting "1619 warn("lld uses blx instruction, no object with architecture supporting "
1484 "feature detected.");1620 "feature detected");
1485 if (Config->ARMJ1J2BranchEncoding == false)
1486 warn("lld uses extended branch encoding, no object with architecture "
1487 "supporting feature detected.");
1488 if (Config->ARMHasMovtMovw == false)
1489 warn("lld may use movt/movw, no object with architecture supporting "
1490 "feature detected.");
1491 }1621 }
14921622
1493 // This adds a .comment section containing a version string. We have to add it1623 // This adds a .comment section containing a version string. We have to add it
1494 // before decompressAndMergeSections because the .comment section is a1624 // before mergeSections because the .comment section is a mergeable section.
1495 // mergeable section.
1496 if (!Config->Relocatable)1625 if (!Config->Relocatable)
1497 InputSections.push_back(createCommentSection());1626 InputSections.push_back(createCommentSection());
14981627
1499 // Do size optimizations: garbage collection, merging of SHF_MERGE sections1628 // Do size optimizations: garbage collection, merging of SHF_MERGE sections
1500 // and identical code folding.1629 // and identical code folding.
1501 decompressSections();
1502 splitSections<ELFT>();1630 splitSections<ELFT>();
1503 markLive<ELFT>();1631 markLive<ELFT>();
1504 demoteSymbols<ELFT>();1632 demoteSharedSymbols<ELFT>();
1505 mergeSections();1633 mergeSections();
1506 if (Config->ICF != ICFLevel::None) {1634 if (Config->ICF != ICFLevel::None) {
1507 findKeepUniqueSections<ELFT>(Args);1635 findKeepUniqueSections<ELFT>(Args);
...@@ -1509,9 +1637,12 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {...@@ -1509,9 +1637,12 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1509 }1637 }
15101638
1511 // Read the callgraph now that we know what was gced or icfed1639 // Read the callgraph now that we know what was gced or icfed
1512 if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))1640 if (Config->CallGraphProfileSort) {
1513 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))1641 if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
1514 readCallGraph(*Buffer);1642 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
1643 readCallGraph(*Buffer);
1644 readCallGraphsFromObjectFiles<ELFT>();
1645 }
15151646
1516 // Write the result to the file.1647 // Write the result to the file.
1517 writeResult<ELFT>();1648 writeResult<ELFT>();
deps/lld/ELF/Driver.h-3
...@@ -42,9 +42,6 @@ private:...@@ -42,9 +42,6 @@ private:
42 // True if we are in --start-lib and --end-lib.42 // True if we are in --start-lib and --end-lib.
43 bool InLib = false;43 bool InLib = false;
4444
45 // True if we are in -format=binary and -format=elf.
46 bool InBinary = false;
47
48 std::vector<InputFile *> Files;45 std::vector<InputFile *> Files;
49};46};
5047
deps/lld/ELF/DriverUtils.cpp+3-2
...@@ -139,8 +139,9 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {...@@ -139,8 +139,9 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
139}139}
140140
141void elf::printHelp() {141void elf::printHelp() {
142 ELFOptTable().PrintHelp(outs(), Config->ProgName.data(), "lld",142 ELFOptTable().PrintHelp(
143 false /*ShowHidden*/, true /*ShowAllAliases*/);143 outs(), (Config->ProgName + " [options] file...").str().c_str(), "lld",
144 false /*ShowHidden*/, true /*ShowAllAliases*/);
144 outs() << "\n";145 outs() << "\n";
145146
146 // Scripts generated by Libtool versions up to at least 2.4.6 (the most147 // Scripts generated by Libtool versions up to at least 2.4.6 (the most
deps/lld/ELF/EhFrame.cpp+2-2
...@@ -44,7 +44,7 @@ public:...@@ -44,7 +44,7 @@ public:
44private:44private:
45 template <class P> void failOn(const P *Loc, const Twine &Msg) {45 template <class P> void failOn(const P *Loc, const Twine &Msg) {
46 fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +46 fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
47 IS->getObjMsg((const uint8_t *)Loc - IS->Data.data()));47 IS->getObjMsg((const uint8_t *)Loc - IS->data().data()));
48 }48 }
4949
50 uint8_t readByte();50 uint8_t readByte();
...@@ -59,7 +59,7 @@ private:...@@ -59,7 +59,7 @@ private:
59}59}
6060
61size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {61size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
62 return EhReader(S, S->Data.slice(Off)).readEhRecordSize();62 return EhReader(S, S->data().slice(Off)).readEhRecordSize();
63}63}
6464
65// .eh_frame section is a sequence of records. Each record starts with65// .eh_frame section is a sequence of records. Each record starts with
deps/lld/ELF/GdbIndex.cpp deleted-101
...@@ -1,101 +0,0 @@
1//===- GdbIndex.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The -gdb-index option instructs the linker to emit a .gdb_index section.
11// The section contains information to make gdb startup faster.
12// The format of the section is described at
13// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html.
14//
15//===----------------------------------------------------------------------===//
16
17#include "GdbIndex.h"
18#include "Symbols.h"
19#include "lld/Common/Memory.h"
20#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
21#include "llvm/Object/ELFObjectFile.h"
22
23using namespace llvm;
24using namespace llvm::object;
25using namespace lld;
26using namespace lld::elf;
27
28template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) {
29 for (InputSectionBase *Sec : Obj->getSections()) {
30 if (!Sec)
31 continue;
32 if (LLDDWARFSection *M = StringSwitch<LLDDWARFSection *>(Sec->Name)
33 .Case(".debug_info", &InfoSection)
34 .Case(".debug_ranges", &RangeSection)
35 .Case(".debug_line", &LineSection)
36 .Default(nullptr)) {
37 Sec->maybeDecompress();
38 M->Data = toStringRef(Sec->Data);
39 M->Sec = Sec;
40 continue;
41 }
42 if (Sec->Name == ".debug_abbrev")
43 AbbrevSection = toStringRef(Sec->Data);
44 else if (Sec->Name == ".debug_gnu_pubnames")
45 GnuPubNamesSection = toStringRef(Sec->Data);
46 else if (Sec->Name == ".debug_gnu_pubtypes")
47 GnuPubTypesSection = toStringRef(Sec->Data);
48 else if (Sec->Name == ".debug_str")
49 StrSection = toStringRef(Sec->Data);
50 }
51}
52
53// Find if there is a relocation at Pos in Sec. The code is a bit
54// more complicated than usual because we need to pass a section index
55// to llvm since it has no idea about InputSection.
56template <class ELFT>
57template <class RelTy>
58Optional<RelocAddrEntry>
59LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos,
60 ArrayRef<RelTy> Rels) const {
61 auto It = std::lower_bound(
62 Rels.begin(), Rels.end(), Pos,
63 [](const RelTy &A, uint64_t B) { return A.r_offset < B; });
64 if (It == Rels.end() || It->r_offset != Pos)
65 return None;
66 const RelTy &Rel = *It;
67
68 const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
69 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
70 const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex];
71 uint32_t SecIndex = File->getSectionIndex(Sym);
72
73 // Broken debug info can point to a non-Defined symbol.
74 auto *DR = dyn_cast<Defined>(&File->getRelocTargetSym(Rel));
75 if (!DR) {
76 error("unsupported relocation target while parsing debug info");
77 return None;
78 }
79 uint64_t Val = DR->Value + getAddend<ELFT>(Rel);
80
81 // FIXME: We should be consistent about always adding the file
82 // offset or not.
83 if (DR->Section->Flags & ELF::SHF_ALLOC)
84 Val += cast<InputSection>(DR->Section)->getOffsetInFile();
85
86 return RelocAddrEntry{SecIndex, Val};
87}
88
89template <class ELFT>
90Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &S,
91 uint64_t Pos) const {
92 auto &Sec = static_cast<const LLDDWARFSection &>(S);
93 if (Sec.Sec->AreRelocsRela)
94 return findAux(*Sec.Sec, Pos, Sec.Sec->template relas<ELFT>());
95 return findAux(*Sec.Sec, Pos, Sec.Sec->template rels<ELFT>());
96}
97
98template class elf::LLDDwarfObj<ELF32LE>;
99template class elf::LLDDwarfObj<ELF32BE>;
100template class elf::LLDDwarfObj<ELF64LE>;
101template class elf::LLDDwarfObj<ELF64BE>;
deps/lld/ELF/GdbIndex.h deleted-70
...@@ -1,70 +0,0 @@
1//===- GdbIndex.h --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===-------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_GDB_INDEX_H
11#define LLD_ELF_GDB_INDEX_H
12
13#include "InputFiles.h"
14#include "llvm/DebugInfo/DWARF/DWARFContext.h"
15#include "llvm/Object/ELF.h"
16
17namespace lld {
18namespace elf {
19
20class InputSection;
21
22struct LLDDWARFSection final : public llvm::DWARFSection {
23 InputSectionBase *Sec = nullptr;
24};
25
26template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject {
27 LLDDWARFSection InfoSection;
28 LLDDWARFSection RangeSection;
29 LLDDWARFSection LineSection;
30 StringRef AbbrevSection;
31 StringRef GnuPubNamesSection;
32 StringRef GnuPubTypesSection;
33 StringRef StrSection;
34
35 template <class RelTy>
36 llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &Sec,
37 uint64_t Pos,
38 ArrayRef<RelTy> Rels) const;
39
40public:
41 explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
42 const llvm::DWARFSection &getInfoSection() const override {
43 return InfoSection;
44 }
45 const llvm::DWARFSection &getRangeSection() const override {
46 return RangeSection;
47 }
48 const llvm::DWARFSection &getLineSection() const override {
49 return LineSection;
50 }
51 StringRef getFileName() const override { return ""; }
52 StringRef getAbbrevSection() const override { return AbbrevSection; }
53 StringRef getStringSection() const override { return StrSection; }
54 StringRef getGnuPubNamesSection() const override {
55 return GnuPubNamesSection;
56 }
57 StringRef getGnuPubTypesSection() const override {
58 return GnuPubTypesSection;
59 }
60 bool isLittleEndian() const override {
61 return ELFT::TargetEndianness == llvm::support::little;
62 }
63 llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
64 uint64_t Pos) const override;
65};
66
67} // namespace elf
68} // namespace lld
69
70#endif
deps/lld/ELF/ICF.cpp+31-4
...@@ -252,7 +252,10 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,...@@ -252,7 +252,10 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
252252
253 auto *DA = dyn_cast<Defined>(&SA);253 auto *DA = dyn_cast<Defined>(&SA);
254 auto *DB = dyn_cast<Defined>(&SB);254 auto *DB = dyn_cast<Defined>(&SB);
255 if (!DA || !DB)255
256 // Placeholder symbols generated by linker scripts look the same now but
257 // may have different values later.
258 if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
256 return false;259 return false;
257260
258 // Relocations referring to absolute symbols are constant-equal if their261 // Relocations referring to absolute symbols are constant-equal if their
...@@ -298,7 +301,7 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,...@@ -298,7 +301,7 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
298template <class ELFT>301template <class ELFT>
299bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {302bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
300 if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||303 if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
301 A->getSize() != B->getSize() || A->Data != B->Data)304 A->getSize() != B->getSize() || A->data() != B->data())
302 return false;305 return false;
303306
304 // If two sections have different output sections, we cannot merge them.307 // If two sections have different output sections, we cannot merge them.
...@@ -420,6 +423,22 @@ void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {...@@ -420,6 +423,22 @@ void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {
420 ++Cnt;423 ++Cnt;
421}424}
422425
426// Combine the hashes of the sections referenced by the given section into its
427// hash.
428template <class ELFT, class RelTy>
429static void combineRelocHashes(unsigned Cnt, InputSection *IS,
430 ArrayRef<RelTy> Rels) {
431 uint32_t Hash = IS->Class[Cnt % 2];
432 for (RelTy Rel : Rels) {
433 Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
434 if (auto *D = dyn_cast<Defined>(&S))
435 if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
436 Hash += RelSec->Class[Cnt % 2];
437 }
438 // Set MSB to 1 to avoid collisions with non-hash IDs.
439 IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
440}
441
423static void print(const Twine &S) {442static void print(const Twine &S) {
424 if (Config->PrintIcfSections)443 if (Config->PrintIcfSections)
425 message(S);444 message(S);
...@@ -435,10 +454,18 @@ template <class ELFT> void ICF<ELFT>::run() {...@@ -435,10 +454,18 @@ template <class ELFT> void ICF<ELFT>::run() {
435454
436 // Initially, we use hash values to partition sections.455 // Initially, we use hash values to partition sections.
437 parallelForEach(Sections, [&](InputSection *S) {456 parallelForEach(Sections, [&](InputSection *S) {
438 // Set MSB to 1 to avoid collisions with non-hash IDs.457 S->Class[0] = xxHash64(S->data());
439 S->Class[0] = xxHash64(S->Data) | (1U << 31);
440 });458 });
441459
460 for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
461 parallelForEach(Sections, [&](InputSection *S) {
462 if (S->AreRelocsRela)
463 combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
464 else
465 combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
466 });
467 }
468
442 // From now on, sections in Sections vector are ordered so that sections469 // From now on, sections in Sections vector are ordered so that sections
443 // in the same equivalence class are consecutive in the vector.470 // in the same equivalence class are consecutive in the vector.
444 std::stable_sort(Sections.begin(), Sections.end(),471 std::stable_sort(Sections.begin(), Sections.end(),
deps/lld/ELF/InputFiles.cpp+74-73
...@@ -46,7 +46,7 @@ std::vector<LazyObjFile *> elf::LazyObjFiles;...@@ -46,7 +46,7 @@ std::vector<LazyObjFile *> elf::LazyObjFiles;
46std::vector<InputFile *> elf::ObjectFiles;46std::vector<InputFile *> elf::ObjectFiles;
47std::vector<InputFile *> elf::SharedFiles;47std::vector<InputFile *> elf::SharedFiles;
4848
49TarWriter *elf::Tar;49std::unique_ptr<TarWriter> elf::Tar;
5050
51InputFile::InputFile(Kind K, MemoryBufferRef M)51InputFile::InputFile(Kind K, MemoryBufferRef M)
52 : MB(M), GroupId(NextGroupId), FileKind(K) {52 : MB(M), GroupId(NextGroupId), FileKind(K) {
...@@ -125,11 +125,7 @@ std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,...@@ -125,11 +125,7 @@ std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
125125
126template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {126template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
127 Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));127 Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
128 const DWARFObject &Obj = Dwarf->getDWARFObj();128 for (std::unique_ptr<DWARFUnit> &CU : Dwarf->compile_units()) {
129 DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE,
130 Config->Wordsize);
131
132 for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units()) {
133 auto Report = [](Error Err) {129 auto Report = [](Error Err) {
134 handleAllErrors(std::move(Err),130 handleAllErrors(std::move(Err),
135 [](ErrorInfoBase &Info) { warn(Info.message()); });131 [](ErrorInfoBase &Info) { warn(Info.message()); });
...@@ -324,17 +320,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,...@@ -324,17 +320,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
324 return Signature;320 return Signature;
325}321}
326322
327template <class ELFT>
328ArrayRef<typename ObjFile<ELFT>::Elf_Word>
329ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
330 const ELFFile<ELFT> &Obj = this->getObj();
331 ArrayRef<Elf_Word> Entries =
332 CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
333 if (Entries.empty() || Entries[0] != GRP_COMDAT)
334 fatal(toString(this) + ": unsupported SHT_GROUP format");
335 return Entries.slice(1);
336}
337
338template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {323template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
339 // On a regular link we don't merge sections if -O0 (default is -O1). This324 // On a regular link we don't merge sections if -O0 (default is -O1). This
340 // sometimes makes the linker significantly faster, although the output will325 // sometimes makes the linker significantly faster, although the output will
...@@ -416,6 +401,11 @@ void ObjFile<ELFT>::initializeSections(...@@ -416,6 +401,11 @@ void ObjFile<ELFT>::initializeSections(
416 continue;401 continue;
417 const Elf_Shdr &Sec = ObjSections[I];402 const Elf_Shdr &Sec = ObjSections[I];
418403
404 if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
405 CGProfile = check(
406 this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
407 &Sec));
408
419 // SHF_EXCLUDE'ed sections are discarded by the linker. However,409 // SHF_EXCLUDE'ed sections are discarded by the linker. However,
420 // if -r is given, we'll let the final link discard such sections.410 // if -r is given, we'll let the final link discard such sections.
421 // This is compatible with GNU.411 // This is compatible with GNU.
...@@ -439,22 +429,34 @@ void ObjFile<ELFT>::initializeSections(...@@ -439,22 +429,34 @@ void ObjFile<ELFT>::initializeSections(
439 case SHT_GROUP: {429 case SHT_GROUP: {
440 // De-duplicate section groups by their signatures.430 // De-duplicate section groups by their signatures.
441 StringRef Signature = getShtGroupSignature(ObjSections, Sec);431 StringRef Signature = getShtGroupSignature(ObjSections, Sec);
442 bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
443 this->Sections[I] = &InputSection::Discarded;432 this->Sections[I] = &InputSection::Discarded;
444433
445 // If it is a new section group, we want to keep group members.434
446 // Group leader sections, which contain indices of group members, are435 ArrayRef<Elf_Word> Entries =
447 // discarded because they are useless beyond this point. The only436 CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
448 // exception is the -r option because in order to produce re-linkable437 if (Entries.empty())
449 // object files, we want to pass through basically everything.438 fatal(toString(this) + ": empty SHT_GROUP");
439
440 // The first word of a SHT_GROUP section contains flags. Currently,
441 // the standard defines only "GRP_COMDAT" flag for the COMDAT group.
442 // An group with the empty flag doesn't define anything; such sections
443 // are just skipped.
444 if (Entries[0] == 0)
445 continue;
446
447 if (Entries[0] != GRP_COMDAT)
448 fatal(toString(this) + ": unsupported SHT_GROUP format");
449
450 bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
450 if (IsNew) {451 if (IsNew) {
451 if (Config->Relocatable)452 if (Config->Relocatable)
452 this->Sections[I] = createInputSection(Sec);453 this->Sections[I] = createInputSection(Sec);
453 continue;454 continue;
454 }455 }
455456
457
456 // Otherwise, discard group members.458 // Otherwise, discard group members.
457 for (uint32_t SecIndex : getShtGroupEntries(Sec)) {459 for (uint32_t SecIndex : Entries.slice(1)) {
458 if (SecIndex >= Size)460 if (SecIndex >= Size)
459 fatal(toString(this) +461 fatal(toString(this) +
460 ": invalid section index in group: " + Twine(SecIndex));462 ": invalid section index in group: " + Twine(SecIndex));
...@@ -478,11 +480,13 @@ void ObjFile<ELFT>::initializeSections(...@@ -478,11 +480,13 @@ void ObjFile<ELFT>::initializeSections(
478 // .ARM.exidx sections have a reverse dependency on the InputSection they480 // .ARM.exidx sections have a reverse dependency on the InputSection they
479 // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.481 // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
480 if (Sec.sh_flags & SHF_LINK_ORDER) {482 if (Sec.sh_flags & SHF_LINK_ORDER) {
481 if (Sec.sh_link >= this->Sections.size())483 InputSectionBase *LinkSec = nullptr;
484 if (Sec.sh_link < this->Sections.size())
485 LinkSec = this->Sections[Sec.sh_link];
486 if (!LinkSec)
482 fatal(toString(this) +487 fatal(toString(this) +
483 ": invalid sh_link index: " + Twine(Sec.sh_link));488 ": invalid sh_link index: " + Twine(Sec.sh_link));
484489
485 InputSectionBase *LinkSec = this->Sections[Sec.sh_link];
486 InputSection *IS = cast<InputSection>(this->Sections[I]);490 InputSection *IS = cast<InputSection>(this->Sections[I]);
487 LinkSec->DependentSections.push_back(IS);491 LinkSec->DependentSections.push_back(IS);
488 if (!isa<InputSection>(LinkSec))492 if (!isa<InputSection>(LinkSec))
...@@ -598,7 +602,7 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {...@@ -598,7 +602,7 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
598// as a given section.602// as a given section.
599static InputSection *toRegularSection(MergeInputSection *Sec) {603static InputSection *toRegularSection(MergeInputSection *Sec) {
600 return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,604 return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
601 Sec->Data, Sec->Name);605 Sec->data(), Sec->Name);
602}606}
603607
604template <class ELFT>608template <class ELFT>
...@@ -618,9 +622,9 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {...@@ -618,9 +622,9 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
618 // FIXME: Retain the first attribute section we see. The eglibc ARM622 // FIXME: Retain the first attribute section we see. The eglibc ARM
619 // dynamic loaders require the presence of an attribute section for dlopen623 // dynamic loaders require the presence of an attribute section for dlopen
620 // to work. In a full implementation we would merge all attribute sections.624 // to work. In a full implementation we would merge all attribute sections.
621 if (InX::ARMAttributes == nullptr) {625 if (In.ARMAttributes == nullptr) {
622 InX::ARMAttributes = make<InputSection>(*this, Sec, Name);626 In.ARMAttributes = make<InputSection>(*this, Sec, Name);
623 return InX::ARMAttributes;627 return In.ARMAttributes;
624 }628 }
625 return &InputSection::Discarded;629 return &InputSection::Discarded;
626 }630 }
...@@ -638,8 +642,16 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {...@@ -638,8 +642,16 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
638 // This section contains relocation information.642 // This section contains relocation information.
639 // If -r is given, we do not interpret or apply relocation643 // If -r is given, we do not interpret or apply relocation
640 // but just copy relocation sections to output.644 // but just copy relocation sections to output.
641 if (Config->Relocatable)645 if (Config->Relocatable) {
642 return make<InputSection>(*this, Sec, Name);646 InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
647 // We want to add a dependency to target, similar like we do for
648 // -emit-relocs below. This is useful for the case when linker script
649 // contains the "/DISCARD/". It is perhaps uncommon to use a script with
650 // -r, but we faced it in the Linux kernel and have to handle such case
651 // and not to crash.
652 Target->DependentSections.push_back(RelocSec);
653 return RelocSec;
654 }
643655
644 if (Target->FirstRelocation)656 if (Target->FirstRelocation)
645 fatal(toString(this) +657 fatal(toString(this) +
...@@ -704,7 +716,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {...@@ -704,7 +716,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
704 // for split stack will include a .note.GNU-split-stack section.716 // for split stack will include a .note.GNU-split-stack section.
705 if (Name == ".note.GNU-split-stack") {717 if (Name == ".note.GNU-split-stack") {
706 if (Config->Relocatable) {718 if (Config->Relocatable) {
707 error("Cannot mix split-stack and non-split-stack in a relocatable link");719 error("cannot mix split-stack and non-split-stack in a relocatable link");
708 return &InputSection::Discarded;720 return &InputSection::Discarded;
709 }721 }
710 this->SplitStack = true;722 this->SplitStack = true;
...@@ -724,7 +736,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {...@@ -724,7 +736,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
724 // sections. Drop those sections to avoid duplicate symbol errors.736 // sections. Drop those sections to avoid duplicate symbol errors.
725 // FIXME: This is glibc PR20543, we should remove this hack once that has been737 // FIXME: This is glibc PR20543, we should remove this hack once that has been
726 // fixed for a while.738 // fixed for a while.
727 if (Name.startswith(".gnu.linkonce."))739 if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
740 Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
728 return &InputSection::Discarded;741 return &InputSection::Discarded;
729742
730 // If we are creating a new .build-id section, strip existing .build-id743 // If we are creating a new .build-id section, strip existing .build-id
...@@ -806,7 +819,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {...@@ -806,7 +819,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
806 if (Sec == &InputSection::Discarded)819 if (Sec == &InputSection::Discarded)
807 return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,820 return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
808 /*CanOmitFromDynSym=*/false, this);821 /*CanOmitFromDynSym=*/false, this);
809 return Symtab->addRegular(Name, StOther, Type, Value, Size, Binding, Sec,822 return Symtab->addDefined(Name, StOther, Type, Value, Size, Binding, Sec,
810 this);823 this);
811 }824 }
812}825}
...@@ -940,8 +953,7 @@ std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {...@@ -940,8 +953,7 @@ std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
940 auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);953 auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
941 Verdef += CurVerdef->vd_next;954 Verdef += CurVerdef->vd_next;
942 unsigned VerdefIndex = CurVerdef->vd_ndx;955 unsigned VerdefIndex = CurVerdef->vd_ndx;
943 if (Verdefs.size() <= VerdefIndex)956 Verdefs.resize(VerdefIndex + 1);
944 Verdefs.resize(VerdefIndex + 1);
945 Verdefs[VerdefIndex] = CurVerdef;957 Verdefs[VerdefIndex] = CurVerdef;
946 }958 }
947959
...@@ -993,25 +1005,25 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {...@@ -993,25 +1005,25 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
993 for (size_t I = 0; I < Syms.size(); ++I) {1005 for (size_t I = 0; I < Syms.size(); ++I) {
994 const Elf_Sym &Sym = Syms[I];1006 const Elf_Sym &Sym = Syms[I];
9951007
996 StringRef Name = CHECK(Sym.getName(this->StringTable), this);
997 if (Sym.isUndefined()) {
998 Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
999 Sym.st_other, Sym.getType(),
1000 /*CanOmitFromDynSym=*/false, this);
1001 S->ExportDynamic = true;
1002 continue;
1003 }
1004
1005 // ELF spec requires that all local symbols precede weak or global1008 // ELF spec requires that all local symbols precede weak or global
1006 // symbols in each symbol table, and the index of first non-local symbol1009 // symbols in each symbol table, and the index of first non-local symbol
1007 // is stored to sh_info. If a local symbol appears after some non-local1010 // is stored to sh_info. If a local symbol appears after some non-local
1008 // symbol, that's a violation of the spec.1011 // symbol, that's a violation of the spec.
1012 StringRef Name = CHECK(Sym.getName(this->StringTable), this);
1009 if (Sym.getBinding() == STB_LOCAL) {1013 if (Sym.getBinding() == STB_LOCAL) {
1010 warn("found local symbol '" + Name +1014 warn("found local symbol '" + Name +
1011 "' in global part of symbol table in file " + toString(this));1015 "' in global part of symbol table in file " + toString(this));
1012 continue;1016 continue;
1013 }1017 }
10141018
1019 if (Sym.isUndefined()) {
1020 Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
1021 Sym.st_other, Sym.getType(),
1022 /*CanOmitFromDynSym=*/false, this);
1023 S->ExportDynamic = true;
1024 continue;
1025 }
1026
1015 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly1027 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly
1016 // assigns VER_NDX_LOCAL to this section global symbol. Here is a1028 // assigns VER_NDX_LOCAL to this section global symbol. Here is a
1017 // workaround for this bug.1029 // workaround for this bug.
...@@ -1054,6 +1066,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {...@@ -1054,6 +1066,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
1054 switch (T.getArch()) {1066 switch (T.getArch()) {
1055 case Triple::aarch64:1067 case Triple::aarch64:
1056 return EM_AARCH64;1068 return EM_AARCH64;
1069 case Triple::amdgcn:
1070 case Triple::r600:
1071 return EM_AMDGPU;
1057 case Triple::arm:1072 case Triple::arm:
1058 case Triple::thumb:1073 case Triple::thumb:
1059 return EM_ARM;1074 return EM_ARM;
...@@ -1064,9 +1079,12 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {...@@ -1064,9 +1079,12 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
1064 case Triple::mips64:1079 case Triple::mips64:
1065 case Triple::mips64el:1080 case Triple::mips64el:
1066 return EM_MIPS;1081 return EM_MIPS;
1082 case Triple::msp430:
1083 return EM_MSP430;
1067 case Triple::ppc:1084 case Triple::ppc:
1068 return EM_PPC;1085 return EM_PPC;
1069 case Triple::ppc64:1086 case Triple::ppc64:
1087 case Triple::ppc64le:
1070 return EM_PPC64;1088 return EM_PPC64;
1071 case Triple::x86:1089 case Triple::x86:
1072 return T.isOSIAMCU() ? EM_IAMCU : EM_386;1090 return T.isOSIAMCU() ? EM_IAMCU : EM_386;
...@@ -1178,7 +1196,7 @@ static ELFKind getELFKind(MemoryBufferRef MB) {...@@ -1178,7 +1196,7 @@ static ELFKind getELFKind(MemoryBufferRef MB) {
1178}1196}
11791197
1180void BinaryFile::parse() {1198void BinaryFile::parse() {
1181 ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());1199 ArrayRef<uint8_t> Data = arrayRefFromStringRef(MB.getBuffer());
1182 auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,1200 auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
1183 8, Data, ".data");1201 8, Data, ".data");
1184 Sections.push_back(Section);1202 Sections.push_back(Section);
...@@ -1192,11 +1210,11 @@ void BinaryFile::parse() {...@@ -1192,11 +1210,11 @@ void BinaryFile::parse() {
1192 if (!isAlnum(S[I]))1210 if (!isAlnum(S[I]))
1193 S[I] = '_';1211 S[I] = '_';
11941212
1195 Symtab->addRegular(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,1213 Symtab->addDefined(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
1196 STB_GLOBAL, Section, nullptr);1214 STB_GLOBAL, Section, nullptr);
1197 Symtab->addRegular(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,1215 Symtab->addDefined(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
1198 Data.size(), 0, STB_GLOBAL, Section, nullptr);1216 Data.size(), 0, STB_GLOBAL, Section, nullptr);
1199 Symtab->addRegular(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,1217 Symtab->addDefined(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
1200 Data.size(), 0, STB_GLOBAL, nullptr, nullptr);1218 Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
1201}1219}
12021220
...@@ -1262,25 +1280,11 @@ template <class ELFT> void LazyObjFile::parse() {...@@ -1262,25 +1280,11 @@ template <class ELFT> void LazyObjFile::parse() {
1262 return;1280 return;
1263 }1281 }
12641282
1265 switch (getELFKind(this->MB)) {1283 if (getELFKind(this->MB) != Config->EKind) {
1266 case ELF32LEKind:1284 error("incompatible file: " + this->MB.getBufferIdentifier());
1267 addElfSymbols<ELF32LE>();
1268 return;
1269 case ELF32BEKind:
1270 addElfSymbols<ELF32BE>();
1271 return;
1272 case ELF64LEKind:
1273 addElfSymbols<ELF64LE>();
1274 return;
1275 case ELF64BEKind:
1276 addElfSymbols<ELF64BE>();
1277 return;1285 return;
1278 default:
1279 llvm_unreachable("getELFKind");
1280 }1286 }
1281}
12821287
1283template <class ELFT> void LazyObjFile::addElfSymbols() {
1284 ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));1288 ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
1285 ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);1289 ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);
12861290
...@@ -1305,12 +1309,9 @@ std::string elf::replaceThinLTOSuffix(StringRef Path) {...@@ -1305,12 +1309,9 @@ std::string elf::replaceThinLTOSuffix(StringRef Path) {
1305 StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;1309 StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
1306 StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;1310 StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
13071311
1308 if (!Path.endswith(Suffix)) {1312 if (Path.consume_back(Suffix))
1309 error("-thinlto-object-suffix-replace=" + Suffix + ";" + Repl +1313 return (Path + Repl).str();
1310 " was given, but " + Path + " does not end with the suffix");1314 return Path;
1311 return "";
1312 }
1313 return (Path.drop_back(Suffix.size()) + Repl).str();
1314}1315}
13151316
1316template void ArchiveFile::parse<ELF32LE>();1317template void ArchiveFile::parse<ELF32LE>();
deps/lld/ELF/InputFiles.h+8-5
...@@ -50,7 +50,7 @@ class Symbol;...@@ -50,7 +50,7 @@ class Symbol;
5050
51// If -reproduce option is given, all input files are written51// If -reproduce option is given, all input files are written
52// to this tar archive.52// to this tar archive.
53extern llvm::TarWriter *Tar;53extern std::unique_ptr<llvm::TarWriter> Tar;
5454
55// Opens a given file.55// Opens a given file.
56llvm::Optional<MemoryBufferRef> readFile(StringRef Path);56llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
...@@ -86,7 +86,9 @@ public:...@@ -86,7 +86,9 @@ public:
8686
87 // Returns object file symbols. It is a runtime error to call this87 // Returns object file symbols. It is a runtime error to call this
88 // function on files of other types.88 // function on files of other types.
89 ArrayRef<Symbol *> getSymbols() {89 ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
90
91 std::vector<Symbol *> &getMutableSymbols() {
90 assert(FileKind == BinaryKind || FileKind == ObjKind ||92 assert(FileKind == BinaryKind || FileKind == ObjKind ||
91 FileKind == BitcodeKind);93 FileKind == BitcodeKind);
92 return Symbols;94 return Symbols;
...@@ -169,10 +171,10 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {...@@ -169,10 +171,10 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
169 typedef typename ELFT::Sym Elf_Sym;171 typedef typename ELFT::Sym Elf_Sym;
170 typedef typename ELFT::Shdr Elf_Shdr;172 typedef typename ELFT::Shdr Elf_Shdr;
171 typedef typename ELFT::Word Elf_Word;173 typedef typename ELFT::Word Elf_Word;
174 typedef typename ELFT::CGProfile Elf_CGProfile;
172175
173 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,176 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
174 const Elf_Shdr &Sec);177 const Elf_Shdr &Sec);
175 ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
176178
177public:179public:
178 static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }180 static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
...@@ -218,6 +220,9 @@ public:...@@ -218,6 +220,9 @@ public:
218 // Pointer to this input file's .llvm_addrsig section, if it has one.220 // Pointer to this input file's .llvm_addrsig section, if it has one.
219 const Elf_Shdr *AddrsigSec = nullptr;221 const Elf_Shdr *AddrsigSec = nullptr;
220222
223 // SHT_LLVM_CALL_GRAPH_PROFILE table
224 ArrayRef<Elf_CGProfile> CGProfile;
225
221private:226private:
222 void227 void
223 initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);228 initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
...@@ -272,8 +277,6 @@ public:...@@ -272,8 +277,6 @@ public:
272 bool AddedToLink = false;277 bool AddedToLink = false;
273278
274private:279private:
275 template <class ELFT> void addElfSymbols();
276
277 uint64_t OffsetInArchive;280 uint64_t OffsetInArchive;
278};281};
279282
deps/lld/ELF/InputSection.cpp+271-188
...@@ -21,7 +21,6 @@...@@ -21,7 +21,6 @@
21#include "Thunks.h"21#include "Thunks.h"
22#include "lld/Common/ErrorHandler.h"22#include "lld/Common/ErrorHandler.h"
23#include "lld/Common/Memory.h"23#include "lld/Common/Memory.h"
24#include "llvm/Object/Decompressor.h"
25#include "llvm/Support/Compiler.h"24#include "llvm/Support/Compiler.h"
26#include "llvm/Support/Compression.h"25#include "llvm/Support/Compression.h"
27#include "llvm/Support/Endian.h"26#include "llvm/Support/Endian.h"
...@@ -64,11 +63,11 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,...@@ -64,11 +63,11 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
64 StringRef Name, Kind SectionKind)63 StringRef Name, Kind SectionKind)
65 : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,64 : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
66 Link),65 Link),
67 File(File), Data(Data) {66 File(File), RawData(Data) {
68 // In order to reduce memory allocation, we assume that mergeable67 // In order to reduce memory allocation, we assume that mergeable
69 // sections are smaller than 4 GiB, which is not an unreasonable68 // sections are smaller than 4 GiB, which is not an unreasonable
70 // assumption as of 2017.69 // assumption as of 2017.
71 if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX)70 if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
72 error(toString(this) + ": section too large");71 error(toString(this) + ": section too large");
7372
74 NumRelocations = 0;73 NumRelocations = 0;
...@@ -80,6 +79,17 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,...@@ -80,6 +79,17 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
80 if (!isPowerOf2_64(V))79 if (!isPowerOf2_64(V))
81 fatal(toString(File) + ": section sh_addralign is not a power of 2");80 fatal(toString(File) + ": section sh_addralign is not a power of 2");
82 this->Alignment = V;81 this->Alignment = V;
82
83 // In ELF, each section can be compressed by zlib, and if compressed,
84 // section name may be mangled by appending "z" (e.g. ".zdebug_info").
85 // If that's the case, demangle section name so that we can handle a
86 // section as if it weren't compressed.
87 if ((Flags & SHF_COMPRESSED) || Name.startswith(".zdebug")) {
88 if (!zlib::isAvailable())
89 error(toString(File) + ": contains a compressed section, " +
90 "but zlib is not available");
91 parseCompressedHeader();
92 }
83}93}
8494
85// Drop SHF_GROUP bit unless we are producing a re-linkable object file.95// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
...@@ -128,13 +138,25 @@ InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,...@@ -128,13 +138,25 @@ InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
128size_t InputSectionBase::getSize() const {138size_t InputSectionBase::getSize() const {
129 if (auto *S = dyn_cast<SyntheticSection>(this))139 if (auto *S = dyn_cast<SyntheticSection>(this))
130 return S->getSize();140 return S->getSize();
141 if (UncompressedSize >= 0)
142 return UncompressedSize;
143 return RawData.size();
144}
145
146void InputSectionBase::uncompress() const {
147 size_t Size = UncompressedSize;
148 UncompressedBuf.reset(new char[Size]);
131149
132 return Data.size();150 if (Error E =
151 zlib::uncompress(toStringRef(RawData), UncompressedBuf.get(), Size))
152 fatal(toString(this) +
153 ": uncompress failed: " + llvm::toString(std::move(E)));
154 RawData = makeArrayRef((uint8_t *)UncompressedBuf.get(), Size);
133}155}
134156
135uint64_t InputSectionBase::getOffsetInFile() const {157uint64_t InputSectionBase::getOffsetInFile() const {
136 const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();158 const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
137 const uint8_t *SecStart = Data.begin();159 const uint8_t *SecStart = data().begin();
138 return SecStart - FileStart;160 return SecStart - FileStart;
139}161}
140162
...@@ -180,34 +202,70 @@ OutputSection *SectionBase::getOutputSection() {...@@ -180,34 +202,70 @@ OutputSection *SectionBase::getOutputSection() {
180 return Sec ? Sec->getParent() : nullptr;202 return Sec ? Sec->getParent() : nullptr;
181}203}
182204
183// Decompress section contents if required. Note that this function205// When a section is compressed, `RawData` consists with a header followed
184// is called from parallelForEach, so it must be thread-safe.206// by zlib-compressed data. This function parses a header to initialize
185void InputSectionBase::maybeDecompress() {207// `UncompressedSize` member and remove the header from `RawData`.
186 if (DecompressBuf)208void InputSectionBase::parseCompressedHeader() {
187 return;209 typedef typename ELF64LE::Chdr Chdr64;
188 if (!(Flags & SHF_COMPRESSED) && !Name.startswith(".zdebug"))210 typedef typename ELF32LE::Chdr Chdr32;
189 return;
190211
191 // Decompress a section.212 // Old-style header
192 Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data),213 if (Name.startswith(".zdebug")) {
193 Config->IsLE, Config->Is64));214 if (!toStringRef(RawData).startswith("ZLIB")) {
215 error(toString(this) + ": corrupted compressed section header");
216 return;
217 }
218 RawData = RawData.slice(4);
194219
195 size_t Size = Dec.getDecompressedSize();220 if (RawData.size() < 8) {
196 DecompressBuf.reset(new char[Size + Name.size()]());221 error(toString(this) + ": corrupted compressed section header");
197 if (Error E = Dec.decompress({DecompressBuf.get(), Size}))222 return;
198 fatal(toString(this) +223 }
199 ": decompress failed: " + llvm::toString(std::move(E)));224
225 UncompressedSize = read64be(RawData.data());
226 RawData = RawData.slice(8);
227
228 // Restore the original section name.
229 // (e.g. ".zdebug_info" -> ".debug_info")
230 Name = Saver.save("." + Name.substr(2));
231 return;
232 }
200233
201 Data = makeArrayRef((uint8_t *)DecompressBuf.get(), Size);234 assert(Flags & SHF_COMPRESSED);
202 Flags &= ~(uint64_t)SHF_COMPRESSED;235 Flags &= ~(uint64_t)SHF_COMPRESSED;
203236
204 // A section name may have been altered if compressed. If that's237 // New-style 64-bit header
205 // the case, restore the original name. (i.e. ".zdebug_" -> ".debug_")238 if (Config->Is64) {
206 if (Name.startswith(".zdebug")) {239 if (RawData.size() < sizeof(Chdr64)) {
207 DecompressBuf[Size] = '.';240 error(toString(this) + ": corrupted compressed section");
208 memcpy(&DecompressBuf[Size + 1], Name.data() + 2, Name.size() - 2);241 return;
209 Name = StringRef(&DecompressBuf[Size], Name.size() - 1);242 }
243
244 auto *Hdr = reinterpret_cast<const Chdr64 *>(RawData.data());
245 if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
246 error(toString(this) + ": unsupported compression type");
247 return;
248 }
249
250 UncompressedSize = Hdr->ch_size;
251 RawData = RawData.slice(sizeof(*Hdr));
252 return;
210 }253 }
254
255 // New-style 32-bit header
256 if (RawData.size() < sizeof(Chdr32)) {
257 error(toString(this) + ": corrupted compressed section");
258 return;
259 }
260
261 auto *Hdr = reinterpret_cast<const Chdr32 *>(RawData.data());
262 if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
263 error(toString(this) + ": unsupported compression type");
264 return;
265 }
266
267 UncompressedSize = Hdr->ch_size;
268 RawData = RawData.slice(sizeof(*Hdr));
211}269}
212270
213InputSection *InputSectionBase::getLinkOrderDep() const {271InputSection *InputSectionBase::getLinkOrderDep() const {
...@@ -230,14 +288,17 @@ Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {...@@ -230,14 +288,17 @@ Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
230// Returns a source location string. Used to construct an error message.288// Returns a source location string. Used to construct an error message.
231template <class ELFT>289template <class ELFT>
232std::string InputSectionBase::getLocation(uint64_t Offset) {290std::string InputSectionBase::getLocation(uint64_t Offset) {
291 std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
292
233 // We don't have file for synthetic sections.293 // We don't have file for synthetic sections.
234 if (getFile<ELFT>() == nullptr)294 if (getFile<ELFT>() == nullptr)
235 return (Config->OutputFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")")295 return (Config->OutputFile + ":(" + SecAndOffset + ")")
236 .str();296 .str();
237297
238 // First check if we can get desired values from debugging information.298 // First check if we can get desired values from debugging information.
239 if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))299 if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
240 return Info->FileName + ":" + std::to_string(Info->Line);300 return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
301 SecAndOffset + ")";
241302
242 // File->SourceFile contains STT_FILE symbol that contains a303 // File->SourceFile contains STT_FILE symbol that contains a
243 // source file name. If it's missing, we use an object file name.304 // source file name. If it's missing, we use an object file name.
...@@ -246,10 +307,10 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {...@@ -246,10 +307,10 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
246 SrcFile = toString(File);307 SrcFile = toString(File);
247308
248 if (Defined *D = getEnclosingFunction<ELFT>(Offset))309 if (Defined *D = getEnclosingFunction<ELFT>(Offset))
249 return SrcFile + ":(function " + toString(*D) + ")";310 return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
250311
251 // If there's no symbol, print out the offset in the section.312 // If there's no symbol, print out the offset in the section.
252 return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();313 return (SrcFile + ":(" + SecAndOffset + ")");
253}314}
254315
255// This function is intended to be used for constructing an error message.316// This function is intended to be used for constructing an error message.
...@@ -259,9 +320,6 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {...@@ -259,9 +320,6 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
259//320//
260// Returns an empty string if there's no way to get line info.321// Returns an empty string if there's no way to get line info.
261std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {322std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
262 // Synthetic sections don't have input files.
263 if (!File)
264 return "";
265 return File->getSrcMsg(Sym, *this, Offset);323 return File->getSrcMsg(Sym, *this, Offset);
266}324}
267325
...@@ -275,9 +333,6 @@ std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {...@@ -275,9 +333,6 @@ std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
275//333//
276// path/to/foo.o:(function bar) in archive path/to/bar.a334// path/to/foo.o:(function bar) in archive path/to/bar.a
277std::string InputSectionBase::getObjMsg(uint64_t Off) {335std::string InputSectionBase::getObjMsg(uint64_t Off) {
278 // Synthetic sections don't have input files.
279 if (!File)
280 return ("<internal>:(" + Name + "+0x" + utohexstr(Off) + ")").str();
281 std::string Filename = File->getName();336 std::string Filename = File->getName();
282337
283 std::string Archive;338 std::string Archive;
...@@ -362,7 +417,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {...@@ -362,7 +417,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
362 // Output section VA is zero for -r, so r_offset is an offset within the417 // Output section VA is zero for -r, so r_offset is an offset within the
363 // section, but for --emit-relocs it is an virtual address.418 // section, but for --emit-relocs it is an virtual address.
364 P->r_offset = Sec->getVA(Rel.r_offset);419 P->r_offset = Sec->getVA(Rel.r_offset);
365 P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type,420 P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
366 Config->IsMips64EL);421 Config->IsMips64EL);
367422
368 if (Sym.Type == STT_SECTION) {423 if (Sym.Type == STT_SECTION) {
...@@ -380,14 +435,14 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {...@@ -380,14 +435,14 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
380 error("STT_SECTION symbol should be defined");435 error("STT_SECTION symbol should be defined");
381 continue;436 continue;
382 }437 }
383 SectionBase *Section = D->Section;438 SectionBase *Section = D->Section->Repl;
384 if (Section == &InputSection::Discarded) {439 if (!Section->Live) {
385 P->setSymbolAndType(0, 0, false);440 P->setSymbolAndType(0, 0, false);
386 continue;441 continue;
387 }442 }
388443
389 int64_t Addend = getAddend<ELFT>(Rel);444 int64_t Addend = getAddend<ELFT>(Rel);
390 const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset;445 const uint8_t *BufLoc = Sec->data().begin() + Rel.r_offset;
391 if (!RelTy::IsRela)446 if (!RelTy::IsRela)
392 Addend = Target->getImplicitAddend(BufLoc, Type);447 Addend = Target->getImplicitAddend(BufLoc, Type);
393448
...@@ -487,6 +542,62 @@ static uint64_t getARMStaticBase(const Symbol &Sym) {...@@ -487,6 +542,62 @@ static uint64_t getARMStaticBase(const Symbol &Sym) {
487 return OS->PtLoad->FirstSec->Addr;542 return OS->PtLoad->FirstSec->Addr;
488}543}
489544
545// For R_RISCV_PC_INDIRECT (R_RISCV_PCREL_LO12_{I,S}), the symbol actually
546// points the corresponding R_RISCV_PCREL_HI20 relocation, and the target VA
547// is calculated using PCREL_HI20's symbol.
548//
549// This function returns the R_RISCV_PCREL_HI20 relocation from
550// R_RISCV_PCREL_LO12's symbol and addend.
551static Relocation *getRISCVPCRelHi20(const Symbol *Sym, uint64_t Addend) {
552 const Defined *D = cast<Defined>(Sym);
553 InputSection *IS = cast<InputSection>(D->Section);
554
555 if (Addend != 0)
556 warn("Non-zero addend in R_RISCV_PCREL_LO12 relocation to " +
557 IS->getObjMsg(D->Value) + " is ignored");
558
559 // Relocations are sorted by offset, so we can use std::equal_range to do
560 // binary search.
561 auto Range = std::equal_range(IS->Relocations.begin(), IS->Relocations.end(),
562 D->Value, RelocationOffsetComparator{});
563 for (auto It = std::get<0>(Range); It != std::get<1>(Range); ++It)
564 if (isRelExprOneOf<R_PC>(It->Expr))
565 return &*It;
566
567 error("R_RISCV_PCREL_LO12 relocation points to " + IS->getObjMsg(D->Value) +
568 " without an associated R_RISCV_PCREL_HI20 relocation");
569 return nullptr;
570}
571
572// A TLS symbol's virtual address is relative to the TLS segment. Add a
573// target-specific adjustment to produce a thread-pointer-relative offset.
574static int64_t getTlsTpOffset() {
575 switch (Config->EMachine) {
576 case EM_ARM:
577 case EM_AARCH64:
578 // Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
579 // followed by a variable amount of alignment padding, followed by the TLS
580 // segment.
581 //
582 // NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld
583 // effectively increases the TCB size to 8 words for Android compatibility.
584 // It accomplishes this by increasing the segment's alignment.
585 return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
586 case EM_386:
587 case EM_X86_64:
588 // Variant 2. The TLS segment is located just before the thread pointer.
589 return -Out::TlsPhdr->p_memsz;
590 case EM_PPC64:
591 // The thread pointer points to a fixed offset from the start of the
592 // executable's TLS segment. An offset of 0x7000 allows a signed 16-bit
593 // offset to reach 0x1000 of TCB/thread-library data and 0xf000 of the
594 // program's TLS segment.
595 return -0x7000;
596 default:
597 llvm_unreachable("unhandled Config->EMachine");
598 }
599}
600
490static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,601static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
491 uint64_t P, const Symbol &Sym, RelExpr Expr) {602 uint64_t P, const Symbol &Sym, RelExpr Expr) {
492 switch (Expr) {603 switch (Expr) {
...@@ -501,38 +612,37 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,...@@ -501,38 +612,37 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
501 case R_ARM_SBREL:612 case R_ARM_SBREL:
502 return Sym.getVA(A) - getARMStaticBase(Sym);613 return Sym.getVA(A) - getARMStaticBase(Sym);
503 case R_GOT:614 case R_GOT:
615 case R_GOT_PLT:
504 case R_RELAX_TLS_GD_TO_IE_ABS:616 case R_RELAX_TLS_GD_TO_IE_ABS:
505 return Sym.getGotVA() + A;617 return Sym.getGotVA() + A;
506 case R_GOTONLY_PC:618 case R_GOTONLY_PC:
507 return InX::Got->getVA() + A - P;619 return In.Got->getVA() + A - P;
508 case R_GOTONLY_PC_FROM_END:620 case R_GOTONLY_PC_FROM_END:
509 return InX::Got->getVA() + A - P + InX::Got->getSize();621 return In.Got->getVA() + A - P + In.Got->getSize();
510 case R_GOTREL:622 case R_GOTREL:
511 return Sym.getVA(A) - InX::Got->getVA();623 return Sym.getVA(A) - In.Got->getVA();
512 case R_GOTREL_FROM_END:624 case R_GOTREL_FROM_END:
513 return Sym.getVA(A) - InX::Got->getVA() - InX::Got->getSize();625 return Sym.getVA(A) - In.Got->getVA() - In.Got->getSize();
514 case R_GOT_FROM_END:626 case R_GOT_FROM_END:
515 case R_RELAX_TLS_GD_TO_IE_END:627 case R_RELAX_TLS_GD_TO_IE_END:
516 return Sym.getGotOffset() + A - InX::Got->getSize();628 return Sym.getGotOffset() + A - In.Got->getSize();
517 case R_TLSLD_GOT_OFF:629 case R_TLSLD_GOT_OFF:
518 case R_GOT_OFF:630 case R_GOT_OFF:
519 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:631 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
520 return Sym.getGotOffset() + A;632 return Sym.getGotOffset() + A;
521 case R_GOT_PAGE_PC:633 case R_AARCH64_GOT_PAGE_PC:
522 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:634 case R_AARCH64_GOT_PAGE_PC_PLT:
635 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
523 return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);636 return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
524 case R_GOT_PC:637 case R_GOT_PC:
525 case R_RELAX_TLS_GD_TO_IE:638 case R_RELAX_TLS_GD_TO_IE:
526 return Sym.getGotVA() + A - P;639 return Sym.getGotVA() + A - P;
527 case R_HINT:640 case R_HEXAGON_GOT:
528 case R_NONE:641 return Sym.getGotVA() - In.GotPlt->getVA();
529 case R_TLSDESC_CALL:
530 case R_TLSLD_HINT:
531 llvm_unreachable("cannot relocate hint relocs");
532 case R_MIPS_GOTREL:642 case R_MIPS_GOTREL:
533 return Sym.getVA(A) - InX::MipsGot->getGp(File);643 return Sym.getVA(A) - In.MipsGot->getGp(File);
534 case R_MIPS_GOT_GP:644 case R_MIPS_GOT_GP:
535 return InX::MipsGot->getGp(File) + A;645 return In.MipsGot->getGp(File) + A;
536 case R_MIPS_GOT_GP_PC: {646 case R_MIPS_GOT_GP_PC: {
537 // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target647 // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
538 // is _gp_disp symbol. In that case we should use the following648 // is _gp_disp symbol. In that case we should use the following
...@@ -541,7 +651,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,...@@ -541,7 +651,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
541 // microMIPS variants of these relocations use slightly different651 // microMIPS variants of these relocations use slightly different
542 // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()652 // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
543 // to correctly handle less-sugnificant bit of the microMIPS symbol.653 // to correctly handle less-sugnificant bit of the microMIPS symbol.
544 uint64_t V = InX::MipsGot->getGp(File) + A - P;654 uint64_t V = In.MipsGot->getGp(File) + A - P;
545 if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)655 if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
546 V += 4;656 V += 4;
547 if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)657 if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)
...@@ -552,31 +662,34 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,...@@ -552,31 +662,34 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
552 // If relocation against MIPS local symbol requires GOT entry, this entry662 // If relocation against MIPS local symbol requires GOT entry, this entry
553 // should be initialized by 'page address'. This address is high 16-bits663 // should be initialized by 'page address'. This address is high 16-bits
554 // of sum the symbol's value and the addend.664 // of sum the symbol's value and the addend.
555 return InX::MipsGot->getVA() +665 return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
556 InX::MipsGot->getPageEntryOffset(File, Sym, A) -666 In.MipsGot->getGp(File);
557 InX::MipsGot->getGp(File);
558 case R_MIPS_GOT_OFF:667 case R_MIPS_GOT_OFF:
559 case R_MIPS_GOT_OFF32:668 case R_MIPS_GOT_OFF32:
560 // In case of MIPS if a GOT relocation has non-zero addend this addend669 // In case of MIPS if a GOT relocation has non-zero addend this addend
561 // should be applied to the GOT entry content not to the GOT entry offset.670 // should be applied to the GOT entry content not to the GOT entry offset.
562 // That is why we use separate expression type.671 // That is why we use separate expression type.
563 return InX::MipsGot->getVA() +672 return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
564 InX::MipsGot->getSymEntryOffset(File, Sym, A) -673 In.MipsGot->getGp(File);
565 InX::MipsGot->getGp(File);
566 case R_MIPS_TLSGD:674 case R_MIPS_TLSGD:
567 return InX::MipsGot->getVA() + InX::MipsGot->getGlobalDynOffset(File, Sym) -675 return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
568 InX::MipsGot->getGp(File);676 In.MipsGot->getGp(File);
569 case R_MIPS_TLSLD:677 case R_MIPS_TLSLD:
570 return InX::MipsGot->getVA() + InX::MipsGot->getTlsIndexOffset(File) -678 return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
571 InX::MipsGot->getGp(File);679 In.MipsGot->getGp(File);
572 case R_PAGE_PC:680 case R_AARCH64_PAGE_PC: {
573 case R_PLT_PAGE_PC: {681 uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
574 uint64_t Dest;682 return getAArch64Page(Val) - getAArch64Page(P);
575 if (Sym.isUndefWeak())683 }
576 Dest = getAArch64Page(A);684 case R_AARCH64_PLT_PAGE_PC: {
577 else685 uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getPltVA() + A;
578 Dest = getAArch64Page(Sym.getVA(A));686 return getAArch64Page(Val) - getAArch64Page(P);
579 return Dest - getAArch64Page(P);687 }
688 case R_RISCV_PC_INDIRECT: {
689 if (const Relocation *HiRel = getRISCVPCRelHi20(&Sym, A))
690 return getRelocTargetVA(File, HiRel->Type, HiRel->Addend, Sym.getVA(),
691 *HiRel->Sym, HiRel->Expr);
692 return 0;
580 }693 }
581 case R_PC: {694 case R_PC: {
582 uint64_t Dest;695 uint64_t Dest;
...@@ -608,16 +721,12 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,...@@ -608,16 +721,12 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
608 return 0;721 return 0;
609722
610 // PPC64 V2 ABI describes two entry points to a function. The global entry723 // PPC64 V2 ABI describes two entry points to a function. The global entry
611 // point sets up the TOC base pointer. When calling a local function, the724 // point is used for calls where the caller and callee (may) have different
612 // call should branch to the local entry point rather than the global entry725 // TOC base pointers and r2 needs to be modified to hold the TOC base for
613 // point. Section 3.4.1 describes using the 3 most significant bits of the726 // the callee. For local calls the caller and callee share the same
614 // st_other field to find out how many instructions there are between the727 // TOC base and so the TOC pointer initialization code should be skipped by
615 // local and global entry point.728 // branching to the local entry point.
616 uint8_t StOther = (Sym.StOther >> 5) & 7;729 return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
617 if (StOther == 0 || StOther == 1)
618 return SymVA - P;
619
620 return SymVA - P + (1LL << StOther);
621 }730 }
622 case R_PPC_TOC:731 case R_PPC_TOC:
623 return getPPC64TocBase() + A;732 return getPPC64TocBase() + A;
...@@ -634,48 +743,32 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,...@@ -634,48 +743,32 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
634 // statically to zero.743 // statically to zero.
635 if (Sym.isTls() && Sym.isUndefWeak())744 if (Sym.isTls() && Sym.isUndefWeak())
636 return 0;745 return 0;
637746 return Sym.getVA(A) + getTlsTpOffset();
638 // For TLS variant 1 the TCB is a fixed size, whereas for TLS variant 2 the
639 // TCB is on unspecified size and content. Targets that implement variant 1
640 // should set TcbSize.
641 if (Target->TcbSize) {
642 // PPC64 V2 ABI has the thread pointer offset into the middle of the TLS
643 // storage area by TlsTpOffset for efficient addressing TCB and up to
644 // 4KB – 8 B of other thread library information (placed before the TCB).
645 // Subtracting this offset will get the address of the first TLS block.
646 if (Target->TlsTpOffset)
647 return Sym.getVA(A) - Target->TlsTpOffset;
648
649 // If thread pointer is not offset into the middle, the first thing in the
650 // TLS storage area is the TCB. Add the TcbSize to get the address of the
651 // first TLS block.
652 return Sym.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align);
653 }
654 return Sym.getVA(A) - Out::TlsPhdr->p_memsz;
655 case R_RELAX_TLS_GD_TO_LE_NEG:747 case R_RELAX_TLS_GD_TO_LE_NEG:
656 case R_NEG_TLS:748 case R_NEG_TLS:
657 return Out::TlsPhdr->p_memsz - Sym.getVA(A);749 return Out::TlsPhdr->p_memsz - Sym.getVA(A);
658 case R_SIZE:750 case R_SIZE:
659 return Sym.getSize() + A;751 return Sym.getSize() + A;
660 case R_TLSDESC:752 case R_TLSDESC:
661 return InX::Got->getGlobalDynAddr(Sym) + A;753 return In.Got->getGlobalDynAddr(Sym) + A;
662 case R_TLSDESC_PAGE:754 case R_AARCH64_TLSDESC_PAGE:
663 return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) -755 return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
664 getAArch64Page(P);756 getAArch64Page(P);
665 case R_TLSGD_GOT:757 case R_TLSGD_GOT:
666 return InX::Got->getGlobalDynOffset(Sym) + A;758 return In.Got->getGlobalDynOffset(Sym) + A;
667 case R_TLSGD_GOT_FROM_END:759 case R_TLSGD_GOT_FROM_END:
668 return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize();760 return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize();
669 case R_TLSGD_PC:761 case R_TLSGD_PC:
670 return InX::Got->getGlobalDynAddr(Sym) + A - P;762 return In.Got->getGlobalDynAddr(Sym) + A - P;
671 case R_TLSLD_GOT_FROM_END:763 case R_TLSLD_GOT_FROM_END:
672 return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();764 return In.Got->getTlsIndexOff() + A - In.Got->getSize();
673 case R_TLSLD_GOT:765 case R_TLSLD_GOT:
674 return InX::Got->getTlsIndexOff() + A;766 return In.Got->getTlsIndexOff() + A;
675 case R_TLSLD_PC:767 case R_TLSLD_PC:
676 return InX::Got->getTlsIndexVA() + A - P;768 return In.Got->getTlsIndexVA() + A - P;
769 default:
770 llvm_unreachable("invalid expression");
677 }771 }
678 llvm_unreachable("Invalid expression");
679}772}
680773
681// This function applies relocations to sections without SHF_ALLOC bit.774// This function applies relocations to sections without SHF_ALLOC bit.
...@@ -808,10 +901,10 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {...@@ -808,10 +901,10 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
808 case R_RELAX_TLS_GD_TO_LE_NEG:901 case R_RELAX_TLS_GD_TO_LE_NEG:
809 Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);902 Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
810 break;903 break;
904 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
811 case R_RELAX_TLS_GD_TO_IE:905 case R_RELAX_TLS_GD_TO_IE:
812 case R_RELAX_TLS_GD_TO_IE_ABS:906 case R_RELAX_TLS_GD_TO_IE_ABS:
813 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:907 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
814 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
815 case R_RELAX_TLS_GD_TO_IE_END:908 case R_RELAX_TLS_GD_TO_IE_END:
816 Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);909 Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
817 break;910 break;
...@@ -848,16 +941,20 @@ static void switchMorestackCallsToMorestackNonSplit(...@@ -848,16 +941,20 @@ static void switchMorestackCallsToMorestackNonSplit(
848 // __morestack inside that function should be switched to941 // __morestack inside that function should be switched to
849 // __morestack_non_split.942 // __morestack_non_split.
850 Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split");943 Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split");
944 if (!MoreStackNonSplit) {
945 error("Mixing split-stack objects requires a definition of "
946 "__morestack_non_split");
947 return;
948 }
851949
852 // Sort both collections to compare addresses efficiently.950 // Sort both collections to compare addresses efficiently.
853 llvm::sort(MorestackCalls.begin(), MorestackCalls.end(),951 llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
854 [](const Relocation *L, const Relocation *R) {952 return L->Offset < R->Offset;
855 return L->Offset < R->Offset;953 });
856 });
857 std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());954 std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
858 llvm::sort(955 llvm::sort(Functions, [](const Defined *L, const Defined *R) {
859 Functions.begin(), Functions.end(),956 return L->Value < R->Value;
860 [](const Defined *L, const Defined *R) { return L->Value < R->Value; });957 });
861958
862 auto It = MorestackCalls.begin();959 auto It = MorestackCalls.begin();
863 for (Defined *F : Functions) {960 for (Defined *F : Functions) {
...@@ -872,8 +969,8 @@ static void switchMorestackCallsToMorestackNonSplit(...@@ -872,8 +969,8 @@ static void switchMorestackCallsToMorestackNonSplit(
872 }969 }
873}970}
874971
875static bool enclosingPrologueAdjusted(uint64_t Offset,972static bool enclosingPrologueAttempted(uint64_t Offset,
876 const DenseSet<Defined *> &Prologues) {973 const DenseSet<Defined *> &Prologues) {
877 for (Defined *F : Prologues)974 for (Defined *F : Prologues)
878 if (F->Value <= Offset && Offset < F->Value + F->Size)975 if (F->Value <= Offset && Offset < F->Value + F->Size)
879 return true;976 return true;
...@@ -889,7 +986,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,...@@ -889,7 +986,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
889 uint8_t *End) {986 uint8_t *End) {
890 if (!getFile<ELFT>()->SplitStack)987 if (!getFile<ELFT>()->SplitStack)
891 return;988 return;
892 DenseSet<Defined *> AdjustedPrologues;989 DenseSet<Defined *> Prologues;
893 std::vector<Relocation *> MorestackCalls;990 std::vector<Relocation *> MorestackCalls;
894991
895 for (Relocation &Rel : Relocations) {992 for (Relocation &Rel : Relocations) {
...@@ -898,15 +995,9 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,...@@ -898,15 +995,9 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
898 if (Rel.Sym->isLocal())995 if (Rel.Sym->isLocal())
899 continue;996 continue;
900997
901 Defined *D = dyn_cast<Defined>(Rel.Sym);
902 // A reference to an undefined symbol was an error, and should not
903 // have gotten to this point.
904 if (!D)
905 continue;
906
907 // Ignore calls into the split-stack api.998 // Ignore calls into the split-stack api.
908 if (D->getName().startswith("__morestack")) {999 if (Rel.Sym->getName().startswith("__morestack")) {
909 if (D->getName().equals("__morestack"))1000 if (Rel.Sym->getName().equals("__morestack"))
910 MorestackCalls.push_back(&Rel);1001 MorestackCalls.push_back(&Rel);
911 continue;1002 continue;
912 }1003 }
...@@ -914,24 +1005,36 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,...@@ -914,24 +1005,36 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
914 // A relocation to non-function isn't relevant. Sometimes1005 // A relocation to non-function isn't relevant. Sometimes
915 // __morestack is not marked as a function, so this check comes1006 // __morestack is not marked as a function, so this check comes
916 // after the name check.1007 // after the name check.
917 if (D->Type != STT_FUNC)1008 if (Rel.Sym->Type != STT_FUNC)
918 continue;1009 continue;
9191010
920 if (enclosingPrologueAdjusted(Rel.Offset, AdjustedPrologues))1011 // If the callee's-file was compiled with split stack, nothing to do. In
1012 // this context, a "Defined" symbol is one "defined by the binary currently
1013 // being produced". So an "undefined" symbol might be provided by a shared
1014 // library. It is not possible to tell how such symbols were compiled, so be
1015 // conservative.
1016 if (Defined *D = dyn_cast<Defined>(Rel.Sym))
1017 if (InputSection *IS = cast_or_null<InputSection>(D->Section))
1018 if (!IS || !IS->getFile<ELFT>() || IS->getFile<ELFT>()->SplitStack)
1019 continue;
1020
1021 if (enclosingPrologueAttempted(Rel.Offset, Prologues))
921 continue;1022 continue;
9221023
923 if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {1024 if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {
924 if (Target->adjustPrologueForCrossSplitStack(Buf + F->Value, End)) {1025 Prologues.insert(F);
925 AdjustedPrologues.insert(F);1026 if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value),
1027 End, F->StOther))
926 continue;1028 continue;
927 }1029 if (!getFile<ELFT>()->SomeNoSplitStack)
1030 error(lld::toString(this) + ": " + F->getName() +
1031 " (with -fsplit-stack) calls " + Rel.Sym->getName() +
1032 " (without -fsplit-stack), but couldn't adjust its prologue");
928 }1033 }
929 if (!getFile<ELFT>()->SomeNoSplitStack)
930 error("function call at " + getErrorLocation(Buf + Rel.Offset) +
931 "crosses a split-stack boundary, but unable " +
932 "to adjust the enclosing function's prologue");
933 }1034 }
934 switchMorestackCallsToMorestackNonSplit(AdjustedPrologues, MorestackCalls);1035
1036 if (Target->NeedsMoreStackNonSplit)
1037 switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls);
935}1038}
9361039
937template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {1040template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
...@@ -960,10 +1063,23 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {...@@ -960,10 +1063,23 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
960 return;1063 return;
961 }1064 }
9621065
1066 // If this is a compressed section, uncompress section contents directly
1067 // to the buffer.
1068 if (UncompressedSize >= 0 && !UncompressedBuf) {
1069 size_t Size = UncompressedSize;
1070 if (Error E = zlib::uncompress(toStringRef(RawData),
1071 (char *)(Buf + OutSecOff), Size))
1072 fatal(toString(this) +
1073 ": uncompress failed: " + llvm::toString(std::move(E)));
1074 uint8_t *BufEnd = Buf + OutSecOff + Size;
1075 relocate<ELFT>(Buf, BufEnd);
1076 return;
1077 }
1078
963 // Copy section contents from source object file to output file1079 // Copy section contents from source object file to output file
964 // and then apply relocations.1080 // and then apply relocations.
965 memcpy(Buf + OutSecOff, Data.data(), Data.size());1081 memcpy(Buf + OutSecOff, data().data(), data().size());
966 uint8_t *BufEnd = Buf + OutSecOff + Data.size();1082 uint8_t *BufEnd = Buf + OutSecOff + data().size();
967 relocate<ELFT>(Buf, BufEnd);1083 relocate<ELFT>(Buf, BufEnd);
968}1084}
9691085
...@@ -1014,7 +1130,7 @@ template <class ELFT> void EhInputSection::split() {...@@ -1014,7 +1130,7 @@ template <class ELFT> void EhInputSection::split() {
1014template <class ELFT, class RelTy>1130template <class ELFT, class RelTy>
1015void EhInputSection::split(ArrayRef<RelTy> Rels) {1131void EhInputSection::split(ArrayRef<RelTy> Rels) {
1016 unsigned RelI = 0;1132 unsigned RelI = 0;
1017 for (size_t Off = 0, End = Data.size(); Off != End;) {1133 for (size_t Off = 0, End = data().size(); Off != End;) {
1018 size_t Size = readEhRecordSize(this, Off);1134 size_t Size = readEhRecordSize(this, Off);
1019 Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));1135 Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
1020 // The empty record is the end marker.1136 // The empty record is the end marker.
...@@ -1094,65 +1210,32 @@ void MergeInputSection::splitIntoPieces() {...@@ -1094,65 +1210,32 @@ void MergeInputSection::splitIntoPieces() {
1094 assert(Pieces.empty());1210 assert(Pieces.empty());
10951211
1096 if (Flags & SHF_STRINGS)1212 if (Flags & SHF_STRINGS)
1097 splitStrings(Data, Entsize);1213 splitStrings(data(), Entsize);
1098 else1214 else
1099 splitNonStrings(Data, Entsize);1215 splitNonStrings(data(), Entsize);
1100
1101 OffsetMap.reserve(Pieces.size());
1102 for (size_t I = 0, E = Pieces.size(); I != E; ++I)
1103 OffsetMap[Pieces[I].InputOff] = I;
1104}
1105
1106template <class It, class T, class Compare>
1107static It fastUpperBound(It First, It Last, const T &Value, Compare Comp) {
1108 size_t Size = std::distance(First, Last);
1109 assert(Size != 0);
1110 while (Size != 1) {
1111 size_t H = Size / 2;
1112 const It MI = First + H;
1113 Size -= H;
1114 First = Comp(Value, *MI) ? First : First + H;
1115 }
1116 return Comp(Value, *First) ? First : First + 1;
1117}
1118
1119// Do binary search to get a section piece at a given input offset.
1120static SectionPiece *findSectionPiece(MergeInputSection *Sec, uint64_t Offset) {
1121 if (Sec->Data.size() <= Offset)
1122 fatal(toString(Sec) + ": entry is past the end of the section");
1123
1124 // Find the element this offset points to.
1125 auto I = fastUpperBound(
1126 Sec->Pieces.begin(), Sec->Pieces.end(), Offset,
1127 [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; });
1128 --I;
1129 return &*I;
1130}1216}
11311217
1132SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {1218SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
1133 // Find a piece starting at a given offset.1219 if (this->data().size() <= Offset)
1134 auto It = OffsetMap.find(Offset);1220 fatal(toString(this) + ": offset is outside the section");
1135 if (It != OffsetMap.end())
1136 return &Pieces[It->second];
11371221
1138 // If Offset is not at beginning of a section piece, it is not in the map.1222 // If Offset is not at beginning of a section piece, it is not in the map.
1139 // In that case we need to search from the original section piece vector.1223 // In that case we need to do a binary search of the original section piece vector.
1140 return findSectionPiece(this, Offset);1224 auto It2 =
1225 llvm::upper_bound(Pieces, Offset, [](uint64_t Offset, SectionPiece P) {
1226 return Offset < P.InputOff;
1227 });
1228 return &It2[-1];
1141}1229}
11421230
1143// Returns the offset in an output section for a given input offset.1231// Returns the offset in an output section for a given input offset.
1144// Because contents of a mergeable section is not contiguous in output,1232// Because contents of a mergeable section is not contiguous in output,
1145// it is not just an addition to a base output offset.1233// it is not just an addition to a base output offset.
1146uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {1234uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {
1147 // Find a string starting at a given offset.
1148 auto It = OffsetMap.find(Offset);
1149 if (It != OffsetMap.end())
1150 return Pieces[It->second].OutputOff;
1151
1152 // If Offset is not at beginning of a section piece, it is not in the map.1235 // If Offset is not at beginning of a section piece, it is not in the map.
1153 // In that case we need to search from the original section piece vector.1236 // In that case we need to search from the original section piece vector.
1154 const SectionPiece &Piece =1237 const SectionPiece &Piece =
1155 *findSectionPiece(const_cast<MergeInputSection *>(this), Offset);1238 *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
1156 uint64_t Addend = Offset - Piece.InputOff;1239 uint64_t Addend = Offset - Piece.InputOff;
1157 return Piece.OutputOff + Addend;1240 return Piece.OutputOff + Addend;
1158}1241}
deps/lld/ELF/InputSection.h+23-15
...@@ -115,7 +115,12 @@ public:...@@ -115,7 +115,12 @@ public:
115 return cast_or_null<ObjFile<ELFT>>(File);115 return cast_or_null<ObjFile<ELFT>>(File);
116 }116 }
117117
118 ArrayRef<uint8_t> Data;118 ArrayRef<uint8_t> data() const {
119 if (UncompressedSize >= 0 && !UncompressedBuf)
120 uncompress();
121 return RawData;
122 }
123
119 uint64_t getOffsetInFile() const;124 uint64_t getOffsetInFile() const;
120125
121 // True if this section has already been placed to a linker script126 // True if this section has already been placed to a linker script
...@@ -169,11 +174,6 @@ public:...@@ -169,11 +174,6 @@ public:
169 template <class ELFT>174 template <class ELFT>
170 Defined *getEnclosingFunction(uint64_t Offset);175 Defined *getEnclosingFunction(uint64_t Offset);
171176
172 // Compilers emit zlib-compressed debug sections if the -gz option
173 // is given. This function checks if this section is compressed, and
174 // if so, decompress in memory.
175 void maybeDecompress();
176
177 // Returns a source location string. Used to construct an error message.177 // Returns a source location string. Used to construct an error message.
178 template <class ELFT> std::string getLocation(uint64_t Offset);178 template <class ELFT> std::string getLocation(uint64_t Offset);
179 std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);179 std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
...@@ -200,15 +200,21 @@ public:...@@ -200,15 +200,21 @@ public:
200200
201201
202 template <typename T> llvm::ArrayRef<T> getDataAs() const {202 template <typename T> llvm::ArrayRef<T> getDataAs() const {
203 size_t S = Data.size();203 size_t S = data().size();
204 assert(S % sizeof(T) == 0);204 assert(S % sizeof(T) == 0);
205 return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));205 return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206 }206 }
207207
208private:208protected:
209 // A pointer that owns decompressed data if a section is compressed by zlib.209 void parseCompressedHeader();
210 void uncompress() const;
211
212 mutable ArrayRef<uint8_t> RawData;
213
214 // A pointer that owns uncompressed data if a section is compressed by zlib.
210 // Since the feature is not used often, this is usually a nullptr.215 // Since the feature is not used often, this is usually a nullptr.
211 std::unique_ptr<char[]> DecompressBuf;216 mutable std::unique_ptr<char[]> UncompressedBuf;
217 int64_t UncompressedSize = -1;
212};218};
213219
214// SectionPiece represents a piece of splittable section contents.220// SectionPiece represents a piece of splittable section contents.
...@@ -247,7 +253,6 @@ public:...@@ -247,7 +253,6 @@ public:
247 // Splittable sections are handled as a sequence of data253 // Splittable sections are handled as a sequence of data
248 // rather than a single large blob of data.254 // rather than a single large blob of data.
249 std::vector<SectionPiece> Pieces;255 std::vector<SectionPiece> Pieces;
250 llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
251256
252 // Returns I'th piece's data. This function is very hot when257 // Returns I'th piece's data. This function is very hot when
253 // string merging is enabled, so we want to inline.258 // string merging is enabled, so we want to inline.
...@@ -255,8 +260,8 @@ public:...@@ -255,8 +260,8 @@ public:
255 llvm::CachedHashStringRef getData(size_t I) const {260 llvm::CachedHashStringRef getData(size_t I) const {
256 size_t Begin = Pieces[I].InputOff;261 size_t Begin = Pieces[I].InputOff;
257 size_t End =262 size_t End =
258 (Pieces.size() - 1 == I) ? Data.size() : Pieces[I + 1].InputOff;263 (Pieces.size() - 1 == I) ? data().size() : Pieces[I + 1].InputOff;
259 return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};264 return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
260 }265 }
261266
262 // Returns the SectionPiece at a given input section offset.267 // Returns the SectionPiece at a given input section offset.
...@@ -277,7 +282,9 @@ struct EhSectionPiece {...@@ -277,7 +282,9 @@ struct EhSectionPiece {
277 unsigned FirstRelocation)282 unsigned FirstRelocation)
278 : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}283 : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
279284
280 ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; }285 ArrayRef<uint8_t> data() {
286 return {Sec->data().data() + this->InputOff, Size};
287 }
281288
282 size_t InputOff;289 size_t InputOff;
283 ssize_t OutputOff = -1;290 ssize_t OutputOff = -1;
...@@ -353,6 +360,7 @@ private:...@@ -353,6 +360,7 @@ private:
353360
354// The list of all input sections.361// The list of all input sections.
355extern std::vector<InputSectionBase *> InputSections;362extern std::vector<InputSectionBase *> InputSections;
363
356} // namespace elf364} // namespace elf
357365
358std::string toString(const elf::InputSectionBase *);366std::string toString(const elf::InputSectionBase *);
deps/lld/ELF/LTO.cpp+25-23
...@@ -67,9 +67,10 @@ static std::string getThinLTOOutputFile(StringRef ModulePath) {...@@ -67,9 +67,10 @@ static std::string getThinLTOOutputFile(StringRef ModulePath) {
67static lto::Config createConfig() {67static lto::Config createConfig() {
68 lto::Config C;68 lto::Config C;
6969
70 // LLD supports the new relocations.70 // LLD supports the new relocations and address-significance tables.
71 C.Options = InitTargetOptionsFromCodeGenFlags();71 C.Options = InitTargetOptionsFromCodeGenFlags();
72 C.Options.RelaxELFRelocations = true;72 C.Options.RelaxELFRelocations = true;
73 C.Options.EmitAddrsig = true;
7374
74 // Always emit a section per function/datum with LTO.75 // Always emit a section per function/datum with LTO.
75 C.Options.FunctionSections = true;76 C.Options.FunctionSections = true;
...@@ -87,6 +88,7 @@ static lto::Config createConfig() {...@@ -87,6 +88,7 @@ static lto::Config createConfig() {
87 C.DiagHandler = diagnosticHandler;88 C.DiagHandler = diagnosticHandler;
88 C.OptLevel = Config->LTOO;89 C.OptLevel = Config->LTOO;
89 C.CPU = GetCPUStr();90 C.CPU = GetCPUStr();
91 C.MAttrs = GetMAttrs();
9092
91 // Set up a custom pipeline if we've been asked to.93 // Set up a custom pipeline if we've been asked to.
92 C.OptPipeline = Config->LTONewPmPasses;94 C.OptPipeline = Config->LTONewPmPasses;
...@@ -101,6 +103,14 @@ static lto::Config createConfig() {...@@ -101,6 +103,14 @@ static lto::Config createConfig() {
101 C.DebugPassManager = Config->LTODebugPassManager;103 C.DebugPassManager = Config->LTODebugPassManager;
102 C.DwoDir = Config->DwoDir;104 C.DwoDir = Config->DwoDir;
103105
106 if (Config->EmitLLVM) {
107 C.PostInternalizeModuleHook = [](size_t Task, const Module &M) {
108 if (std::unique_ptr<raw_fd_ostream> OS = openFile(Config->OutputFile))
109 WriteBitcodeToFile(M, *OS, false);
110 return false;
111 };
112 }
113
104 if (Config->SaveTemps)114 if (Config->SaveTemps)
105 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",115 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
106 /*UseInputModulePath*/ true));116 /*UseInputModulePath*/ true));
...@@ -108,18 +118,14 @@ static lto::Config createConfig() {...@@ -108,18 +118,14 @@ static lto::Config createConfig() {
108}118}
109119
110BitcodeCompiler::BitcodeCompiler() {120BitcodeCompiler::BitcodeCompiler() {
121 // Initialize IndexFile.
122 if (!Config->ThinLTOIndexOnlyArg.empty())
123 IndexFile = openFile(Config->ThinLTOIndexOnlyArg);
124
111 // Initialize LTOObj.125 // Initialize LTOObj.
112 lto::ThinBackend Backend;126 lto::ThinBackend Backend;
113
114 if (Config->ThinLTOIndexOnly) {127 if (Config->ThinLTOIndexOnly) {
115 StringRef Path = Config->ThinLTOIndexOnlyArg;128 auto OnIndexWrite = [&](StringRef S) { ThinIndices.erase(S); };
116 if (!Path.empty())
117 IndexFile = openFile(Path);
118
119 auto OnIndexWrite = [&](const std::string &Identifier) {
120 ObjectToIndexFileState[Identifier] = true;
121 };
122
123 Backend = lto::createWriteIndexesThinBackend(129 Backend = lto::createWriteIndexesThinBackend(
124 Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,130 Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
125 Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);131 Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
...@@ -132,10 +138,10 @@ BitcodeCompiler::BitcodeCompiler() {...@@ -132,10 +138,10 @@ BitcodeCompiler::BitcodeCompiler() {
132138
133 // Initialize UsedStartStop.139 // Initialize UsedStartStop.
134 for (Symbol *Sym : Symtab->getSymbols()) {140 for (Symbol *Sym : Symtab->getSymbols()) {
135 StringRef Name = Sym->getName();141 StringRef S = Sym->getName();
136 for (StringRef Prefix : {"__start_", "__stop_"})142 for (StringRef Prefix : {"__start_", "__stop_"})
137 if (Name.startswith(Prefix))143 if (S.startswith(Prefix))
138 UsedStartStop.insert(Name.substr(Prefix.size()));144 UsedStartStop.insert(S.substr(Prefix.size()));
139 }145 }
140}146}
141147
...@@ -151,7 +157,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {...@@ -151,7 +157,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
151 bool IsExec = !Config->Shared && !Config->Relocatable;157 bool IsExec = !Config->Shared && !Config->Relocatable;
152158
153 if (Config->ThinLTOIndexOnly)159 if (Config->ThinLTOIndexOnly)
154 ObjectToIndexFileState.insert({Obj.getName(), false});160 ThinIndices.insert(Obj.getName());
155161
156 ArrayRef<Symbol *> Syms = F.getSymbols();162 ArrayRef<Symbol *> Syms = F.getSymbols();
157 ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();163 ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
...@@ -240,15 +246,11 @@ std::vector<InputFile *> BitcodeCompiler::compile() {...@@ -240,15 +246,11 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
240 Cache));246 Cache));
241247
242 // Emit empty index files for non-indexed files248 // Emit empty index files for non-indexed files
243 if (Config->ThinLTOIndexOnly) {249 for (StringRef S : ThinIndices) {
244 for (auto &Identifier : ObjectToIndexFileState)250 std::string Path = getThinLTOOutputFile(S);
245 if (!Identifier.getValue()) {251 openFile(Path + ".thinlto.bc");
246 std::string Path = getThinLTOOutputFile(Identifier.getKey());252 if (Config->ThinLTOEmitImportsFiles)
247 openFile(Path + ".thinlto.bc");253 openFile(Path + ".imports");
248
249 if (Config->ThinLTOEmitImportsFiles)
250 openFile(Path + ".imports");
251 }
252 }254 }
253255
254 // If LazyObjFile has not been added to link, emit empty index files.256 // If LazyObjFile has not been added to link, emit empty index files.
deps/lld/ELF/LTO.h+1-1
...@@ -55,7 +55,7 @@ private:...@@ -55,7 +55,7 @@ private:
55 std::vector<std::unique_ptr<MemoryBuffer>> Files;55 std::vector<std::unique_ptr<MemoryBuffer>> Files;
56 llvm::DenseSet<StringRef> UsedStartStop;56 llvm::DenseSet<StringRef> UsedStartStop;
57 std::unique_ptr<llvm::raw_fd_ostream> IndexFile;57 std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
58 llvm::StringMap<bool> ObjectToIndexFileState;58 llvm::DenseSet<StringRef> ThinIndices;
59};59};
60} // namespace elf60} // namespace elf
61} // namespace lld61} // namespace lld
deps/lld/ELF/LinkerScript.cpp+10-23
...@@ -169,7 +169,7 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {...@@ -169,7 +169,7 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
169 // Define a symbol.169 // Define a symbol.
170 Symbol *Sym;170 Symbol *Sym;
171 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;171 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
172 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,172 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
173 /*CanOmitFromDynSym*/ false,173 /*CanOmitFromDynSym*/ false,
174 /*File*/ nullptr);174 /*File*/ nullptr);
175 ExprValue Value = Cmd->Expression();175 ExprValue Value = Cmd->Expression();
...@@ -202,13 +202,14 @@ static void declareSymbol(SymbolAssignment *Cmd) {...@@ -202,13 +202,14 @@ static void declareSymbol(SymbolAssignment *Cmd) {
202 // We can't calculate final value right now.202 // We can't calculate final value right now.
203 Symbol *Sym;203 Symbol *Sym;
204 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;204 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
205 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,205 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
206 /*CanOmitFromDynSym*/ false,206 /*CanOmitFromDynSym*/ false,
207 /*File*/ nullptr);207 /*File*/ nullptr);
208 replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,208 replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
209 STT_NOTYPE, 0, 0, nullptr);209 STT_NOTYPE, 0, 0, nullptr);
210 Cmd->Sym = cast<Defined>(Sym);210 Cmd->Sym = cast<Defined>(Sym);
211 Cmd->Provide = false;211 Cmd->Provide = false;
212 Sym->ScriptDefined = true;
212}213}
213214
214// This method is used to handle INSERT AFTER statement. Here we rebuild215// This method is used to handle INSERT AFTER statement. Here we rebuild
...@@ -414,18 +415,16 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {...@@ -414,18 +415,16 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
414415
415void LinkerScript::discard(ArrayRef<InputSection *> V) {416void LinkerScript::discard(ArrayRef<InputSection *> V) {
416 for (InputSection *S : V) {417 for (InputSection *S : V) {
417 if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||418 if (S == In.ShStrTab || S == In.RelaDyn || S == In.RelrDyn)
418 S == InX::DynStrTab || S == InX::RelaPlt || S == InX::RelaDyn ||
419 S == InX::RelrDyn)
420 error("discarding " + S->Name + " section is not allowed");419 error("discarding " + S->Name + " section is not allowed");
421420
422 // You can discard .hash and .gnu.hash sections by linker scripts. Since421 // You can discard .hash and .gnu.hash sections by linker scripts. Since
423 // they are synthesized sections, we need to handle them differently than422 // they are synthesized sections, we need to handle them differently than
424 // other regular sections.423 // other regular sections.
425 if (S == InX::GnuHashTab)424 if (S == In.GnuHashTab)
426 InX::GnuHashTab = nullptr;425 In.GnuHashTab = nullptr;
427 if (S == InX::HashTab)426 if (S == In.HashTab)
428 InX::HashTab = nullptr;427 In.HashTab = nullptr;
429428
430 S->Assigned = false;429 S->Assigned = false;
431 S->Live = false;430 S->Live = false;
...@@ -701,6 +700,7 @@ uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {...@@ -701,6 +700,7 @@ uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {
701}700}
702701
703void LinkerScript::output(InputSection *S) {702void LinkerScript::output(InputSection *S) {
703 assert(Ctx->OutSec == S->getParent());
704 uint64_t Before = advance(0, 1);704 uint64_t Before = advance(0, 1);
705 uint64_t Pos = advance(S->getSize(), S->Alignment);705 uint64_t Pos = advance(S->getSize(), S->Alignment);
706 S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;706 S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
...@@ -816,21 +816,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {...@@ -816,21 +816,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
816 // Handle a single input section description command.816 // Handle a single input section description command.
817 // It calculates and assigns the offsets for each section and also817 // It calculates and assigns the offsets for each section and also
818 // updates the output section size.818 // updates the output section size.
819 auto *Cmd = cast<InputSectionDescription>(Base);819 for (InputSection *Sec : cast<InputSectionDescription>(Base)->Sections)
820 for (InputSection *Sec : Cmd->Sections) {
821 // We tentatively added all synthetic sections at the beginning and
822 // removed empty ones afterwards (because there is no way to know
823 // whether they were going be empty or not other than actually running
824 // linker scripts.) We need to ignore remains of empty sections.
825 if (auto *S = dyn_cast<SyntheticSection>(Sec))
826 if (S->empty())
827 continue;
828
829 if (!Sec->Live)
830 continue;
831 assert(Ctx->OutSec == Sec->getParent());
832 output(Sec);820 output(Sec);
833 }
834 }821 }
835}822}
836823
deps/lld/ELF/LinkerScript.h+7-5
...@@ -30,12 +30,13 @@ namespace lld {...@@ -30,12 +30,13 @@ namespace lld {
30namespace elf {30namespace elf {
3131
32class Defined;32class Defined;
33class Symbol;
34class InputSectionBase;
35class InputSection;33class InputSection;
36class OutputSection;
37class InputSectionBase;34class InputSectionBase;
35class InputSectionBase;
36class OutputSection;
38class SectionBase;37class SectionBase;
38class Symbol;
39class ThunkSection;
3940
40// This represents an r-value in the linker script.41// This represents an r-value in the linker script.
41struct ExprValue {42struct ExprValue {
...@@ -145,7 +146,9 @@ struct MemoryRegion {...@@ -145,7 +146,9 @@ struct MemoryRegion {
145// Also it may be surrounded with SORT() command, so contains sorting rules.146// Also it may be surrounded with SORT() command, so contains sorting rules.
146struct SectionPattern {147struct SectionPattern {
147 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)148 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
148 : ExcludedFilePat(Pat1), SectionPat(Pat2) {}149 : ExcludedFilePat(Pat1), SectionPat(Pat2),
150 SortOuter(SortSectionPolicy::Default),
151 SortInner(SortSectionPolicy::Default) {}
149152
150 StringMatcher ExcludedFilePat;153 StringMatcher ExcludedFilePat;
151 StringMatcher SectionPat;154 StringMatcher SectionPat;
...@@ -153,7 +156,6 @@ struct SectionPattern {...@@ -153,7 +156,6 @@ struct SectionPattern {
153 SortSectionPolicy SortInner;156 SortSectionPolicy SortInner;
154};157};
155158
156class ThunkSection;
157struct InputSectionDescription : BaseCommand {159struct InputSectionDescription : BaseCommand {
158 InputSectionDescription(StringRef FilePattern)160 InputSectionDescription(StringRef FilePattern)
159 : BaseCommand(InputSectionKind), FilePat(FilePattern) {}161 : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
deps/lld/ELF/MapFile.cpp+6-5
...@@ -126,7 +126,7 @@ static void printEhFrame(raw_ostream &OS, OutputSection *OSec) {...@@ -126,7 +126,7 @@ static void printEhFrame(raw_ostream &OS, OutputSection *OSec) {
126 };126 };
127127
128 // Gather section pieces.128 // Gather section pieces.
129 for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) {129 for (const CieRecord *Rec : In.EhFrame->getCieRecords()) {
130 Add(*Rec->Cie);130 Add(*Rec->Cie);
131 for (const EhSectionPiece *Fde : Rec->Fdes)131 for (const EhSectionPiece *Fde : Rec->Fdes)
132 Add(*Fde);132 Add(*Fde);
...@@ -163,17 +163,18 @@ void elf::writeMapFile() {...@@ -163,17 +163,18 @@ void elf::writeMapFile() {
163 OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)163 OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)
164 << " Size Align Out In Symbol\n";164 << " Size Align Out In Symbol\n";
165165
166 OutputSection* OSec = nullptr;
166 for (BaseCommand *Base : Script->SectionCommands) {167 for (BaseCommand *Base : Script->SectionCommands) {
167 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {168 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
168 if (Cmd->Provide && !Cmd->Sym)169 if (Cmd->Provide && !Cmd->Sym)
169 continue;170 continue;
170 //FIXME: calculate and print LMA.171 uint64_t LMA = OSec ? OSec->getLMA() + Cmd->Addr - OSec->getVA(0) : 0;
171 writeHeader(OS, Cmd->Addr, 0, Cmd->Size, 1);172 writeHeader(OS, Cmd->Addr, LMA, Cmd->Size, 1);
172 OS << Cmd->CommandString << '\n';173 OS << Cmd->CommandString << '\n';
173 continue;174 continue;
174 }175 }
175176
176 auto *OSec = cast<OutputSection>(Base);177 OSec = cast<OutputSection>(Base);
177 writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);178 writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
178 OS << OSec->Name << '\n';179 OS << OSec->Name << '\n';
179180
...@@ -181,7 +182,7 @@ void elf::writeMapFile() {...@@ -181,7 +182,7 @@ void elf::writeMapFile() {
181 for (BaseCommand *Base : OSec->SectionCommands) {182 for (BaseCommand *Base : OSec->SectionCommands) {
182 if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {183 if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
183 for (InputSection *IS : ISD->Sections) {184 for (InputSection *IS : ISD->Sections) {
184 if (IS == InX::EhFrame) {185 if (IS == In.EhFrame) {
185 printEhFrame(OS, OSec);186 printEhFrame(OS, OSec);
186 continue;187 continue;
187 }188 }
deps/lld/ELF/MarkLive.cpp+11-4
...@@ -45,7 +45,7 @@ using namespace lld::elf;...@@ -45,7 +45,7 @@ using namespace lld::elf;
45template <class ELFT>45template <class ELFT>
46static typename ELFT::uint getAddend(InputSectionBase &Sec,46static typename ELFT::uint getAddend(InputSectionBase &Sec,
47 const typename ELFT::Rel &Rel) {47 const typename ELFT::Rel &Rel) {
48 return Target->getImplicitAddend(Sec.Data.begin() + Rel.r_offset,48 return Target->getImplicitAddend(Sec.data().begin() + Rel.r_offset,
49 Rel.getType(Config->IsMips64EL));49 Rel.getType(Config->IsMips64EL));
50}50}
5151
...@@ -250,9 +250,10 @@ template <class ELFT> static void doGcSections() {...@@ -250,9 +250,10 @@ template <class ELFT> static void doGcSections() {
250250
251 if (Sec->Flags & SHF_LINK_ORDER)251 if (Sec->Flags & SHF_LINK_ORDER)
252 continue;252 continue;
253 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))253
254 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) {
254 Enqueue(Sec, 0);255 Enqueue(Sec, 0);
255 else if (isValidCIdentifier(Sec->Name)) {256 } else if (isValidCIdentifier(Sec->Name)) {
256 CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);257 CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
257 CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);258 CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
258 }259 }
...@@ -267,10 +268,16 @@ template <class ELFT> static void doGcSections() {...@@ -267,10 +268,16 @@ template <class ELFT> static void doGcSections() {
267// input sections. This function make some or all of them on268// input sections. This function make some or all of them on
268// so that they are emitted to the output file.269// so that they are emitted to the output file.
269template <class ELFT> void elf::markLive() {270template <class ELFT> void elf::markLive() {
270 // If -gc-sections is missing, no sections are removed.
271 if (!Config->GcSections) {271 if (!Config->GcSections) {
272 // If -gc-sections is missing, no sections are removed.
272 for (InputSectionBase *Sec : InputSections)273 for (InputSectionBase *Sec : InputSections)
273 Sec->Live = true;274 Sec->Live = true;
275
276 // If a DSO defines a symbol referenced in a regular object, it is needed.
277 for (Symbol *Sym : Symtab->getSymbols())
278 if (auto *S = dyn_cast<SharedSymbol>(Sym))
279 if (S->IsUsedInRegularObj && !S->isWeak())
280 S->getFile<ELFT>().IsNeeded = true;
274 return;281 return;
275 }282 }
276283
deps/lld/ELF/Options.td+23-1
...@@ -42,6 +42,12 @@ defm compress_debug_sections:...@@ -42,6 +42,12 @@ defm compress_debug_sections:
4242
43defm defsym: Eq<"defsym", "Define a symbol alias">, MetaVarName<"<symbol>=<value>">;43defm defsym: Eq<"defsym", "Define a symbol alias">, MetaVarName<"<symbol>=<value>">;
4444
45defm split_stack_adjust_size
46 : Eq<"split-stack-adjust-size",
47 "Specify adjustment to stack size when a split-stack function calls a "
48 "non-split-stack function">,
49 MetaVarName<"<value>">;
50
45defm library_path:51defm library_path:
46 Eq<"library-path", "Add a directory to the library search path">, MetaVarName<"<dir>">;52 Eq<"library-path", "Add a directory to the library search path">, MetaVarName<"<dir>">;
4753
...@@ -68,6 +74,10 @@ defm as_needed: B<"as-needed",...@@ -68,6 +74,10 @@ defm as_needed: B<"as-needed",
68defm call_graph_ordering_file:74defm call_graph_ordering_file:
69 Eq<"call-graph-ordering-file", "Layout sections to optimize the given callgraph">;75 Eq<"call-graph-ordering-file", "Layout sections to optimize the given callgraph">;
7076
77defm call_graph_profile_sort: B<"call-graph-profile-sort",
78 "Reorder sections with call graph profile (default)",
79 "Do not reorder sections with call graph profile">;
80
71// -chroot doesn't have a help text because it is an internal option.81// -chroot doesn't have a help text because it is an internal option.
72def chroot: Separate<["--", "-"], "chroot">;82def chroot: Separate<["--", "-"], "chroot">;
7383
...@@ -132,7 +142,7 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">,...@@ -132,7 +142,7 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">,
132defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;142defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
133143
134defm execute_only: B<"execute-only",144defm execute_only: B<"execute-only",
135 "Do not mark executable sections readable",145 "Mark executable sections unreadable",
136 "Mark executable sections readable (default)">;146 "Mark executable sections readable (default)">;
137147
138defm export_dynamic: B<"export-dynamic",148defm export_dynamic: B<"export-dynamic",
...@@ -245,6 +255,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags",...@@ -245,6 +255,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags",
245 "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",255 "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
246 "Use SHT_RELR / DT_RELR* tags (default)">;256 "Use SHT_RELR / DT_RELR* tags (default)">;
247257
258def pic_veneer: F<"pic-veneer">,
259 HelpText<"Always generate position independent thunks (veneers)">;
260
248defm pie: B<"pie",261defm pie: B<"pie",
249 "Create a position independent executable",262 "Create a position independent executable",
250 "Do not create a position independent executable (default)">;263 "Do not create a position independent executable (default)">;
...@@ -315,6 +328,10 @@ defm threads: B<"threads",...@@ -315,6 +328,10 @@ defm threads: B<"threads",
315 "Run the linker multi-threaded (default)",328 "Run the linker multi-threaded (default)",
316 "Do not run the linker multi-threaded">;329 "Do not run the linker multi-threaded">;
317330
331defm toc_optimize : B<"toc-optimize",
332 "(PowerPC64) Enable TOC related optimizations (default)",
333 "(PowerPC64) Disable TOC related optimizations">;
334
318def trace: F<"trace">, HelpText<"Print the names of the input files">;335def trace: F<"trace">, HelpText<"Print the names of the input files">;
319336
320defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;337defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
...@@ -348,6 +365,10 @@ defm warn_common: B<"warn-common",...@@ -348,6 +365,10 @@ defm warn_common: B<"warn-common",
348 "Warn about duplicate common symbols",365 "Warn about duplicate common symbols",
349 "Do not warn about duplicate common symbols (default)">;366 "Do not warn about duplicate common symbols (default)">;
350367
368defm warn_ifunc_textrel: B<"warn-ifunc-textrel",
369 "Warn about using ifunc symbols with text relocations",
370 "Do not warn about using ifunc symbols with text relocations (default)">;
371
351defm warn_symbol_ordering: B<"warn-symbol-ordering",372defm warn_symbol_ordering: B<"warn-symbol-ordering",
352 "Warn about problems with the symbol ordering file (default)",373 "Warn about problems with the symbol ordering file (default)",
353 "Do not warn about problems with the symbol ordering file">;374 "Do not warn about problems with the symbol ordering file">;
...@@ -440,6 +461,7 @@ def: F<"plugin-opt=debug-pass-manager">,...@@ -440,6 +461,7 @@ def: F<"plugin-opt=debug-pass-manager">,
440def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, HelpText<"Alias for -disable-verify">;461def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, HelpText<"Alias for -disable-verify">;
441def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">,462def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">,
442 HelpText<"Directory to store .dwo files when LTO and debug fission are used">;463 HelpText<"Directory to store .dwo files when LTO and debug fission are used">;
464def plugin_opt_emit_llvm: F<"plugin-opt=emit-llvm">;
443def: J<"plugin-opt=jobs=">, Alias<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">;465def: J<"plugin-opt=jobs=">, Alias<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">;
444def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">;466def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">;
445def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">;467def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">;
deps/lld/ELF/OutputSections.cpp+14-12
...@@ -25,6 +25,7 @@...@@ -25,6 +25,7 @@
25using namespace llvm;25using namespace llvm;
26using namespace llvm::dwarf;26using namespace llvm::dwarf;
27using namespace llvm::object;27using namespace llvm::object;
28using namespace llvm::support::endian;
28using namespace llvm::ELF;29using namespace llvm::ELF;
2930
30using namespace lld;31using namespace lld;
...@@ -32,7 +33,6 @@ using namespace lld::elf;...@@ -32,7 +33,6 @@ using namespace lld::elf;
3233
33uint8_t Out::First;34uint8_t Out::First;
34PhdrEntry *Out::TlsPhdr;35PhdrEntry *Out::TlsPhdr;
35OutputSection *Out::DebugInfo;
36OutputSection *Out::ElfHeader;36OutputSection *Out::ElfHeader;
37OutputSection *Out::ProgramHeaders;37OutputSection *Out::ProgramHeaders;
38OutputSection *Out::PreinitArray;38OutputSection *Out::PreinitArray;
...@@ -171,11 +171,12 @@ void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) {...@@ -171,11 +171,12 @@ void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) {
171171
172// Fill [Buf, Buf + Size) with Filler.172// Fill [Buf, Buf + Size) with Filler.
173// This is used for linker script "=fillexp" command.173// This is used for linker script "=fillexp" command.
174static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {174static void fill(uint8_t *Buf, size_t Size,
175 const std::array<uint8_t, 4> &Filler) {
175 size_t I = 0;176 size_t I = 0;
176 for (; I + 4 < Size; I += 4)177 for (; I + 4 < Size; I += 4)
177 memcpy(Buf + I, &Filler, 4);178 memcpy(Buf + I, Filler.data(), 4);
178 memcpy(Buf + I, &Filler, Size - I);179 memcpy(Buf + I, Filler.data(), Size - I);
179}180}
180181
181// Compress section contents if this section contains debug info.182// Compress section contents if this section contains debug info.
...@@ -236,8 +237,9 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {...@@ -236,8 +237,9 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
236237
237 // Write leading padding.238 // Write leading padding.
238 std::vector<InputSection *> Sections = getInputSections(this);239 std::vector<InputSection *> Sections = getInputSections(this);
239 uint32_t Filler = getFiller();240 std::array<uint8_t, 4> Filler = getFiller();
240 if (Filler)241 bool NonZeroFiller = read32(Filler.data()) != 0;
242 if (NonZeroFiller)
241 fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);243 fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
242244
243 parallelForEachN(0, Sections.size(), [&](size_t I) {245 parallelForEachN(0, Sections.size(), [&](size_t I) {
...@@ -245,7 +247,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {...@@ -245,7 +247,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
245 IS->writeTo<ELFT>(Buf);247 IS->writeTo<ELFT>(Buf);
246248
247 // Fill gaps between sections.249 // Fill gaps between sections.
248 if (Filler) {250 if (NonZeroFiller) {
249 uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();251 uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
250 uint8_t *End;252 uint8_t *End;
251 if (I + 1 == Sections.size())253 if (I + 1 == Sections.size())
...@@ -270,13 +272,13 @@ static void finalizeShtGroup(OutputSection *OS,...@@ -270,13 +272,13 @@ static void finalizeShtGroup(OutputSection *OS,
270272
271 // sh_link field for SHT_GROUP sections should contain the section index of273 // sh_link field for SHT_GROUP sections should contain the section index of
272 // the symbol table.274 // the symbol table.
273 OS->Link = InX::SymTab->getParent()->SectionIndex;275 OS->Link = In.SymTab->getParent()->SectionIndex;
274276
275 // sh_info then contain index of an entry in symbol table section which277 // sh_info then contain index of an entry in symbol table section which
276 // provides signature of the section group.278 // provides signature of the section group.
277 ObjFile<ELFT> *Obj = Section->getFile<ELFT>();279 ObjFile<ELFT> *Obj = Section->getFile<ELFT>();
278 ArrayRef<Symbol *> Symbols = Obj->getSymbols();280 ArrayRef<Symbol *> Symbols = Obj->getSymbols();
279 OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]);281 OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
280}282}
281283
282template <class ELFT> void OutputSection::finalize() {284template <class ELFT> void OutputSection::finalize() {
...@@ -308,7 +310,7 @@ template <class ELFT> void OutputSection::finalize() {...@@ -308,7 +310,7 @@ template <class ELFT> void OutputSection::finalize() {
308 if (isa<SyntheticSection>(First))310 if (isa<SyntheticSection>(First))
309 return;311 return;
310312
311 Link = InX::SymTab->getParent()->SectionIndex;313 Link = In.SymTab->getParent()->SectionIndex;
312 // sh_info for SHT_REL[A] sections should contain the section header index of314 // sh_info for SHT_REL[A] sections should contain the section header index of
313 // the section to which the relocation applies.315 // the section to which the relocation applies.
314 InputSectionBase *S = First->getRelocatedSection();316 InputSectionBase *S = First->getRelocatedSection();
...@@ -406,12 +408,12 @@ void OutputSection::sortInitFini() {...@@ -406,12 +408,12 @@ void OutputSection::sortInitFini() {
406 sort([](InputSectionBase *S) { return getPriority(S->Name); });408 sort([](InputSectionBase *S) { return getPriority(S->Name); });
407}409}
408410
409uint32_t OutputSection::getFiller() {411std::array<uint8_t, 4> OutputSection::getFiller() {
410 if (Filler)412 if (Filler)
411 return *Filler;413 return *Filler;
412 if (Flags & SHF_EXECINSTR)414 if (Flags & SHF_EXECINSTR)
413 return Target->TrapInstr;415 return Target->TrapInstr;
414 return 0;416 return {0, 0, 0, 0};
415}417}
416418
417template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);419template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
deps/lld/ELF/OutputSections.h+3-3
...@@ -17,6 +17,7 @@...@@ -17,6 +17,7 @@
17#include "lld/Common/LLVM.h"17#include "lld/Common/LLVM.h"
18#include "llvm/MC/StringTableBuilder.h"18#include "llvm/MC/StringTableBuilder.h"
19#include "llvm/Object/ELF.h"19#include "llvm/Object/ELF.h"
20#include <array>
2021
21namespace lld {22namespace lld {
22namespace elf {23namespace elf {
...@@ -94,7 +95,7 @@ public:...@@ -94,7 +95,7 @@ public:
94 Expr SubalignExpr;95 Expr SubalignExpr;
95 std::vector<BaseCommand *> SectionCommands;96 std::vector<BaseCommand *> SectionCommands;
96 std::vector<StringRef> Phdrs;97 std::vector<StringRef> Phdrs;
97 llvm::Optional<uint32_t> Filler;98 llvm::Optional<std::array<uint8_t, 4>> Filler;
98 ConstraintKind Constraint = ConstraintKind::NoConstraint;99 ConstraintKind Constraint = ConstraintKind::NoConstraint;
99 std::string Location;100 std::string Location;
100 std::string MemoryRegionName;101 std::string MemoryRegionName;
...@@ -117,7 +118,7 @@ private:...@@ -117,7 +118,7 @@ private:
117 std::vector<uint8_t> ZDebugHeader;118 std::vector<uint8_t> ZDebugHeader;
118 llvm::SmallVector<char, 1> CompressedData;119 llvm::SmallVector<char, 1> CompressedData;
119120
120 uint32_t getFiller();121 std::array<uint8_t, 4> getFiller();
121};122};
122123
123int getPriority(StringRef S);124int getPriority(StringRef S);
...@@ -130,7 +131,6 @@ std::vector<InputSection *> getInputSections(OutputSection* OS);...@@ -130,7 +131,6 @@ std::vector<InputSection *> getInputSections(OutputSection* OS);
130struct Out {131struct Out {
131 static uint8_t First;132 static uint8_t First;
132 static PhdrEntry *TlsPhdr;133 static PhdrEntry *TlsPhdr;
133 static OutputSection *DebugInfo;
134 static OutputSection *ElfHeader;134 static OutputSection *ElfHeader;
135 static OutputSection *ProgramHeaders;135 static OutputSection *ProgramHeaders;
136 static OutputSection *PreinitArray;136 static OutputSection *PreinitArray;
deps/lld/ELF/Relocations.cpp+215-150
...@@ -50,6 +50,7 @@...@@ -50,6 +50,7 @@
50#include "SyntheticSections.h"50#include "SyntheticSections.h"
51#include "Target.h"51#include "Target.h"
52#include "Thunks.h"52#include "Thunks.h"
53#include "lld/Common/ErrorHandler.h"
53#include "lld/Common/Memory.h"54#include "lld/Common/Memory.h"
54#include "lld/Common/Strings.h"55#include "lld/Common/Strings.h"
55#include "llvm/ADT/SmallSet.h"56#include "llvm/ADT/SmallSet.h"
...@@ -65,6 +66,14 @@ using namespace llvm::support::endian;...@@ -65,6 +66,14 @@ using namespace llvm::support::endian;
65using namespace lld;66using namespace lld;
66using namespace lld::elf;67using namespace lld::elf;
6768
69static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
70 for (BaseCommand *Base : Script->SectionCommands)
71 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
72 if (Cmd->Sym == &Sym)
73 return Cmd->Location;
74 return None;
75}
76
68// Construct a message in the following format.77// Construct a message in the following format.
69//78//
70// >>> defined in /home/alice/src/foo.o79// >>> defined in /home/alice/src/foo.o
...@@ -72,8 +81,13 @@ using namespace lld::elf;...@@ -72,8 +81,13 @@ using namespace lld::elf;
72// >>> /home/alice/src/bar.o:(.text+0x1)81// >>> /home/alice/src/bar.o:(.text+0x1)
73static std::string getLocation(InputSectionBase &S, const Symbol &Sym,82static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
74 uint64_t Off) {83 uint64_t Off) {
75 std::string Msg =84 std::string Msg = "\n>>> defined in ";
76 "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";85 if (Sym.File)
86 Msg += toString(Sym.File);
87 else if (Optional<std::string> Loc = getLinkerScriptLocation(Sym))
88 Msg += *Loc;
89
90 Msg += "\n>>> referenced by ";
77 std::string Src = S.getSrcMsg(Sym, Off);91 std::string Src = S.getSrcMsg(Sym, Off);
78 if (!Src.empty())92 if (!Src.empty())
79 Msg += Src + "\n>>> ";93 Msg += Src + "\n>>> ";
...@@ -90,12 +104,12 @@ static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,...@@ -90,12 +104,12 @@ static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,
90 InputSectionBase &C, uint64_t Offset,104 InputSectionBase &C, uint64_t Offset,
91 int64_t Addend, RelExpr Expr) {105 int64_t Addend, RelExpr Expr) {
92 if (Expr == R_MIPS_TLSLD) {106 if (Expr == R_MIPS_TLSLD) {
93 InX::MipsGot->addTlsIndex(*C.File);107 In.MipsGot->addTlsIndex(*C.File);
94 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});108 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
95 return 1;109 return 1;
96 }110 }
97 if (Expr == R_MIPS_TLSGD) {111 if (Expr == R_MIPS_TLSGD) {
98 InX::MipsGot->addDynTlsEntry(*C.File, Sym);112 In.MipsGot->addDynTlsEntry(*C.File, Sym);
99 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});113 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
100 return 1;114 return 1;
101 }115 }
...@@ -128,17 +142,17 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,...@@ -128,17 +142,17 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,
128142
129 auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) {143 auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) {
130 if (Dyn)144 if (Dyn)
131 InX::RelaDyn->addReloc(Type, InX::Got, Off, Dest);145 In.RelaDyn->addReloc(Type, In.Got, Off, Dest);
132 else146 else
133 InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});147 In.Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});
134 };148 };
135149
136 // Local Dynamic is for access to module local TLS variables, while still150 // Local Dynamic is for access to module local TLS variables, while still
137 // being suitable for being dynamically loaded via dlopen.151 // being suitable for being dynamically loaded via dlopen.
138 // GOT[e0] is the module index, with a special value of 0 for the current152 // GOT[e0] is the module index, with a special value of 0 for the current
139 // module. GOT[e1] is unused. There only needs to be one module index entry.153 // module. GOT[e1] is unused. There only needs to be one module index entry.
140 if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) {154 if (Expr == R_TLSLD_PC && In.Got->addTlsIndex()) {
141 AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel,155 AddTlsReloc(In.Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
142 NeedDynId ? nullptr : &Sym, NeedDynId);156 NeedDynId ? nullptr : &Sym, NeedDynId);
143 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});157 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
144 return 1;158 return 1;
...@@ -148,8 +162,8 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,...@@ -148,8 +162,8 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,
148 // the module index and offset of symbol in TLS block we can fill these in162 // the module index and offset of symbol in TLS block we can fill these in
149 // using static GOT relocations.163 // using static GOT relocations.
150 if (Expr == R_TLSGD_PC) {164 if (Expr == R_TLSGD_PC) {
151 if (InX::Got->addDynTlsEntry(Sym)) {165 if (In.Got->addDynTlsEntry(Sym)) {
152 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);166 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
153 AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId);167 AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId);
154 AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym,168 AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym,
155 NeedDynOff);169 NeedDynOff);
...@@ -165,9 +179,6 @@ template <class ELFT>...@@ -165,9 +179,6 @@ template <class ELFT>
165static unsigned179static unsigned
166handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,180handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
167 typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {181 typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
168 if (!(C.Flags & SHF_ALLOC))
169 return 0;
170
171 if (!Sym.isTls())182 if (!Sym.isTls())
172 return 0;183 return 0;
173184
...@@ -176,12 +187,12 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,...@@ -176,12 +187,12 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
176 if (Config->EMachine == EM_MIPS)187 if (Config->EMachine == EM_MIPS)
177 return handleMipsTlsRelocation(Type, Sym, C, Offset, Addend, Expr);188 return handleMipsTlsRelocation(Type, Sym, C, Offset, Addend, Expr);
178189
179 if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&190 if (isRelExprOneOf<R_TLSDESC, R_AARCH64_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&
180 Config->Shared) {191 Config->Shared) {
181 if (InX::Got->addDynTlsEntry(Sym)) {192 if (In.Got->addDynTlsEntry(Sym)) {
182 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);193 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
183 InX::RelaDyn->addReloc(194 In.RelaDyn->addReloc(
184 {Target->TlsDescRel, InX::Got, Off, !Sym.IsPreemptible, &Sym, 0});195 {Target->TlsDescRel, In.Got, Off, !Sym.IsPreemptible, &Sym, 0});
185 }196 }
186 if (Expr != R_TLSDESC_CALL)197 if (Expr != R_TLSDESC_CALL)
187 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});198 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
...@@ -199,9 +210,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,...@@ -199,9 +210,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
199 }210 }
200 if (Expr == R_TLSLD_HINT)211 if (Expr == R_TLSLD_HINT)
201 return 1;212 return 1;
202 if (InX::Got->addTlsIndex())213 if (In.Got->addTlsIndex())
203 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got,214 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got,
204 InX::Got->getTlsIndexOff(), nullptr);215 In.Got->getTlsIndexOff(), nullptr);
205 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});216 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
206 return 1;217 return 1;
207 }218 }
...@@ -223,29 +234,29 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,...@@ -223,29 +234,29 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
223 return 1;234 return 1;
224 }235 }
225 if (!Sym.isInGot()) {236 if (!Sym.isInGot()) {
226 InX::Got->addEntry(Sym);237 In.Got->addEntry(Sym);
227 uint64_t Off = Sym.getGotOffset();238 uint64_t Off = Sym.getGotOffset();
228 InX::Got->Relocations.push_back({R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});239 In.Got->Relocations.push_back(
240 {R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});
229 }241 }
230 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});242 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
231 return 1;243 return 1;
232 }244 }
233245
234 if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT,246 if (isRelExprOneOf<R_TLSDESC, R_AARCH64_TLSDESC_PAGE, R_TLSDESC_CALL,
235 R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) {247 R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) {
236 if (Config->Shared) {248 if (Config->Shared) {
237 if (InX::Got->addDynTlsEntry(Sym)) {249 if (In.Got->addDynTlsEntry(Sym)) {
238 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);250 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
239 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, Off, &Sym);251 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym);
240252
241 // If the symbol is preemptible we need the dynamic linker to write253 // If the symbol is preemptible we need the dynamic linker to write
242 // the offset too.254 // the offset too.
243 uint64_t OffsetOff = Off + Config->Wordsize;255 uint64_t OffsetOff = Off + Config->Wordsize;
244 if (Sym.IsPreemptible)256 if (Sym.IsPreemptible)
245 InX::RelaDyn->addReloc(Target->TlsOffsetRel, InX::Got, OffsetOff,257 In.RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff, &Sym);
246 &Sym);
247 else258 else
248 InX::Got->Relocations.push_back(259 In.Got->Relocations.push_back(
249 {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});260 {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});
250 }261 }
251 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});262 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
...@@ -259,9 +270,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,...@@ -259,9 +270,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
259 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,270 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
260 Offset, Addend, &Sym});271 Offset, Addend, &Sym});
261 if (!Sym.isInGot()) {272 if (!Sym.isInGot()) {
262 InX::Got->addEntry(Sym);273 In.Got->addEntry(Sym);
263 InX::RelaDyn->addReloc(Target->TlsGotRel, InX::Got, Sym.getGotOffset(),274 In.RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(),
264 &Sym);275 &Sym);
265 }276 }
266 } else {277 } else {
267 C.Relocations.push_back(278 C.Relocations.push_back(
...@@ -273,13 +284,14 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,...@@ -273,13 +284,14 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
273284
274 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally285 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
275 // defined.286 // defined.
276 if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) &&287 if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_AARCH64_GOT_PAGE_PC,
288 R_GOT_OFF, R_TLSIE_HINT>(Expr) &&
277 !Config->Shared && !Sym.IsPreemptible) {289 !Config->Shared && !Sym.IsPreemptible) {
278 C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});290 C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});
279 return 1;291 return 1;
280 }292 }
281293
282 if (Expr == R_TLSDESC_CALL)294 if (Expr == R_TLSIE_HINT)
283 return 1;295 return 1;
284 return 0;296 return 0;
285}297}
...@@ -325,24 +337,26 @@ static bool isAbsoluteValue(const Symbol &Sym) {...@@ -325,24 +337,26 @@ static bool isAbsoluteValue(const Symbol &Sym) {
325337
326// Returns true if Expr refers a PLT entry.338// Returns true if Expr refers a PLT entry.
327static bool needsPlt(RelExpr Expr) {339static bool needsPlt(RelExpr Expr) {
328 return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_PLT_PAGE_PC>(Expr);340 return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_AARCH64_PLT_PAGE_PC,
341 R_GOT_PLT, R_AARCH64_GOT_PAGE_PC_PLT>(Expr);
329}342}
330343
331// Returns true if Expr refers a GOT entry. Note that this function344// Returns true if Expr refers a GOT entry. Note that this function
332// returns false for TLS variables even though they need GOT, because345// returns false for TLS variables even though they need GOT, because
333// TLS variables uses GOT differently than the regular variables.346// TLS variables uses GOT differently than the regular variables.
334static bool needsGot(RelExpr Expr) {347static bool needsGot(RelExpr Expr) {
335 return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,348 return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
336 R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,349 R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
337 R_GOT_FROM_END>(Expr);350 R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END,
351 R_GOT_PLT>(Expr);
338}352}
339353
340// True if this expression is of the form Sym - X, where X is a position in the354// True if this expression is of the form Sym - X, where X is a position in the
341// file (PC, or GOT for example).355// file (PC, or GOT for example).
342static bool isRelExpr(RelExpr Expr) {356static bool isRelExpr(RelExpr Expr) {
343 return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,357 return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
344 R_PPC_CALL, R_PPC_CALL_PLT, R_PAGE_PC,358 R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC,
345 R_RELAX_GOT_PC>(Expr);359 R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr);
346}360}
347361
348// Returns true if a given relocation can be computed at link-time.362// Returns true if a given relocation can be computed at link-time.
...@@ -357,18 +371,19 @@ static bool isRelExpr(RelExpr Expr) {...@@ -357,18 +371,19 @@ static bool isRelExpr(RelExpr Expr) {
357static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,371static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
358 InputSectionBase &S, uint64_t RelOff) {372 InputSectionBase &S, uint64_t RelOff) {
359 // These expressions always compute a constant373 // These expressions always compute a constant
360 if (isRelExprOneOf<374 if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF,
361 R_GOT_FROM_END, R_GOT_OFF, R_TLSLD_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,375 R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
362 R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,376 R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD,
363 R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,377 R_AARCH64_GOT_PAGE_PC, R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC,
364 R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END,378 R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT,
365 R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT,379 R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT,
366 R_TLSLD_HINT>(E))380 R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, R_HINT,
381 R_TLSLD_HINT, R_TLSIE_HINT>(E))
367 return true;382 return true;
368383
369 // These never do, except if the entire file is position dependent or if384 // These never do, except if the entire file is position dependent or if
370 // only the low bits are used.385 // only the low bits are used.
371 if (E == R_GOT || E == R_PLT || E == R_TLSDESC)386 if (E == R_GOT || E == R_GOT_PLT || E == R_PLT || E == R_TLSDESC)
372 return Target->usesOnlyLowPageBits(Type) || !Config->Pic;387 return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
373388
374 if (Sym.IsPreemptible)389 if (Sym.IsPreemptible)
...@@ -414,10 +429,14 @@ static RelExpr toPlt(RelExpr Expr) {...@@ -414,10 +429,14 @@ static RelExpr toPlt(RelExpr Expr) {
414 return R_PPC_CALL_PLT;429 return R_PPC_CALL_PLT;
415 case R_PC:430 case R_PC:
416 return R_PLT_PC;431 return R_PLT_PC;
417 case R_PAGE_PC:432 case R_AARCH64_PAGE_PC:
418 return R_PLT_PAGE_PC;433 return R_AARCH64_PLT_PAGE_PC;
434 case R_AARCH64_GOT_PAGE_PC:
435 return R_AARCH64_GOT_PAGE_PC_PLT;
419 case R_ABS:436 case R_ABS:
420 return R_PLT;437 return R_PLT;
438 case R_GOT:
439 return R_GOT_PLT;
421 default:440 default:
422 return Expr;441 return Expr;
423 }442 }
...@@ -466,7 +485,7 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {...@@ -466,7 +485,7 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
466 SmallSet<SharedSymbol *, 4> Ret;485 SmallSet<SharedSymbol *, 4> Ret;
467 for (const Elf_Sym &S : File.getGlobalELFSyms()) {486 for (const Elf_Sym &S : File.getGlobalELFSyms()) {
468 if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||487 if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
469 S.st_value != SS.Value)488 S.getType() == STT_TLS || S.st_value != SS.Value)
470 continue;489 continue;
471 StringRef Name = check(S.getName(File.getStringTable()));490 StringRef Name = check(S.getName(File.getStringTable()));
472 Symbol *Sym = Symtab->find(Name);491 Symbol *Sym = Symtab->find(Name);
...@@ -489,6 +508,7 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,...@@ -489,6 +508,7 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
489 Sym.PltIndex = Old.PltIndex;508 Sym.PltIndex = Old.PltIndex;
490 Sym.GotIndex = Old.GotIndex;509 Sym.GotIndex = Old.GotIndex;
491 Sym.VerdefIndex = Old.VerdefIndex;510 Sym.VerdefIndex = Old.VerdefIndex;
511 Sym.PPC64BranchltIndex = Old.PPC64BranchltIndex;
492 Sym.IsPreemptible = true;512 Sym.IsPreemptible = true;
493 Sym.ExportDynamic = true;513 Sym.ExportDynamic = true;
494 Sym.IsUsedInRegularObj = true;514 Sym.IsUsedInRegularObj = true;
...@@ -549,9 +569,9 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {...@@ -549,9 +569,9 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
549 BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",569 BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
550 SymSize, SS.Alignment);570 SymSize, SS.Alignment);
551 if (IsReadOnly)571 if (IsReadOnly)
552 InX::BssRelRo->getParent()->addSection(Sec);572 In.BssRelRo->getParent()->addSection(Sec);
553 else573 else
554 InX::Bss->getParent()->addSection(Sec);574 In.Bss->getParent()->addSection(Sec);
555575
556 // Look through the DSO's dynamic symbol table for aliases and create a576 // Look through the DSO's dynamic symbol table for aliases and create a
557 // dynamic symbol for each one. This causes the copy relocation to correctly577 // dynamic symbol for each one. This causes the copy relocation to correctly
...@@ -559,7 +579,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {...@@ -559,7 +579,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
559 for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))579 for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
560 replaceWithDefined(*Sym, Sec, 0, Sym->Size);580 replaceWithDefined(*Sym, Sec, 0, Sym->Size);
561581
562 InX::RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);582 In.RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
563}583}
564584
565// MIPS has an odd notion of "paired" relocations to calculate addends.585// MIPS has an odd notion of "paired" relocations to calculate addends.
...@@ -583,7 +603,7 @@ static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,...@@ -583,7 +603,7 @@ static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
583 if (PairTy == R_MIPS_NONE)603 if (PairTy == R_MIPS_NONE)
584 return 0;604 return 0;
585605
586 const uint8_t *Buf = Sec.Data.data();606 const uint8_t *Buf = Sec.data().data();
587 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);607 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
588608
589 // To make things worse, paired relocations might not be contiguous in609 // To make things worse, paired relocations might not be contiguous in
...@@ -611,7 +631,7 @@ static int64_t computeAddend(const RelTy &Rel, const RelTy *End,...@@ -611,7 +631,7 @@ static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
611 if (RelTy::IsRela) {631 if (RelTy::IsRela) {
612 Addend = getAddend<ELFT>(Rel);632 Addend = getAddend<ELFT>(Rel);
613 } else {633 } else {
614 const uint8_t *Buf = Sec.Data.data();634 const uint8_t *Buf = Sec.data().data();
615 Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);635 Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
616 }636 }
617637
...@@ -627,9 +647,6 @@ static int64_t computeAddend(const RelTy &Rel, const RelTy *End,...@@ -627,9 +647,6 @@ static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
627// Returns true if this function printed out an error message.647// Returns true if this function printed out an error message.
628static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,648static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
629 uint64_t Offset) {649 uint64_t Offset) {
630 if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
631 return false;
632
633 if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())650 if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())
634 return false;651 return false;
635652
...@@ -646,6 +663,10 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,...@@ -646,6 +663,10 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
646 Msg += Src + "\n>>> ";663 Msg += Src + "\n>>> ";
647 Msg += Sec.getObjMsg(Offset);664 Msg += Sec.getObjMsg(Offset);
648665
666 if (Sym.getName().startswith("_ZTV"))
667 Msg += "\nthe vtable symbol may be undefined because the class is missing "
668 "its key function (see https://lld.llvm.org/missingkeyfunction)";
669
649 if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||670 if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
650 Config->NoinhibitExec) {671 Config->NoinhibitExec) {
651 warn(Msg);672 warn(Msg);
...@@ -700,7 +721,7 @@ public:...@@ -700,7 +721,7 @@ public:
700 while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)721 while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)
701 ++I;722 ++I;
702 if (I == Pieces.size())723 if (I == Pieces.size())
703 return Off;724 fatal(".eh_frame: relocation is not in any piece");
704725
705 // Pieces must be contiguous, so there must be no holes in between.726 // Pieces must be contiguous, so there must be no holes in between.
706 assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");727 assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");
...@@ -726,13 +747,13 @@ static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,...@@ -726,13 +747,13 @@ static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,
726 // RelrDyn sections don't support odd offsets. Also, RelrDyn sections747 // RelrDyn sections don't support odd offsets. Also, RelrDyn sections
727 // don't store the addend values, so we must write it to the relocated748 // don't store the addend values, so we must write it to the relocated
728 // address.749 // address.
729 if (InX::RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {750 if (In.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
730 IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});751 IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
731 InX::RelrDyn->Relocs.push_back({IS, OffsetInSec});752 In.RelrDyn->Relocs.push_back({IS, OffsetInSec});
732 return;753 return;
733 }754 }
734 InX::RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend,755 In.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, Expr,
735 Expr, Type);756 Type);
736}757}
737758
738template <class ELFT, class GotPltSection>759template <class ELFT, class GotPltSection>
...@@ -745,9 +766,16 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,...@@ -745,9 +766,16 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
745}766}
746767
747template <class ELFT> static void addGotEntry(Symbol &Sym) {768template <class ELFT> static void addGotEntry(Symbol &Sym) {
748 InX::Got->addEntry(Sym);769 In.Got->addEntry(Sym);
770
771 RelExpr Expr;
772 if (Sym.isTls())
773 Expr = R_TLS;
774 else if (Sym.isGnuIFunc())
775 Expr = R_PLT;
776 else
777 Expr = R_ABS;
749778
750 RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
751 uint64_t Off = Sym.getGotOffset();779 uint64_t Off = Sym.getGotOffset();
752780
753 // If a GOT slot value can be calculated at link-time, which is now,781 // If a GOT slot value can be calculated at link-time, which is now,
...@@ -760,19 +788,19 @@ template <class ELFT> static void addGotEntry(Symbol &Sym) {...@@ -760,19 +788,19 @@ template <class ELFT> static void addGotEntry(Symbol &Sym) {
760 bool IsLinkTimeConstant =788 bool IsLinkTimeConstant =
761 !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));789 !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
762 if (IsLinkTimeConstant) {790 if (IsLinkTimeConstant) {
763 InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});791 In.Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});
764 return;792 return;
765 }793 }
766794
767 // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that795 // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
768 // the GOT slot will be fixed at load-time.796 // the GOT slot will be fixed at load-time.
769 if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {797 if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {
770 addRelativeReloc(InX::Got, Off, &Sym, 0, R_ABS, Target->GotRel);798 addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->GotRel);
771 return;799 return;
772 }800 }
773 InX::RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel,801 In.RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got,
774 InX::Got, Off, &Sym, 0,802 Off, &Sym, 0, Sym.IsPreemptible ? R_ADDEND : R_ABS,
775 Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel);803 Target->GotRel);
776}804}
777805
778// Return true if we can define a symbol in the executable that806// Return true if we can define a symbol in the executable that
...@@ -825,7 +853,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,...@@ -825,7 +853,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
825 addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);853 addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
826 return;854 return;
827 } else if (RelType Rel = Target->getDynRel(Type)) {855 } else if (RelType Rel = Target->getDynRel(Type)) {
828 InX::RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);856 In.RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);
829857
830 // MIPS ABI turns using of GOT and dynamic relocations inside out.858 // MIPS ABI turns using of GOT and dynamic relocations inside out.
831 // While regular ABI uses dynamic relocations to fill up GOT entries859 // While regular ABI uses dynamic relocations to fill up GOT entries
...@@ -843,7 +871,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,...@@ -843,7 +871,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
843 // a dynamic relocation.871 // a dynamic relocation.
844 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19872 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
845 if (Config->EMachine == EM_MIPS)873 if (Config->EMachine == EM_MIPS)
846 InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);874 In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
847 return;875 return;
848 }876 }
849 }877 }
...@@ -930,10 +958,9 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,...@@ -930,10 +958,9 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
930 "' cannot be preempted; recompile with -fPIE" +958 "' cannot be preempted; recompile with -fPIE" +
931 getLocation(Sec, Sym, Offset));959 getLocation(Sec, Sym, Offset));
932 if (!Sym.isInPlt())960 if (!Sym.isInPlt())
933 addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,961 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
934 Sym);
935 if (!Sym.isDefined())962 if (!Sym.isDefined())
936 replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0);963 replaceWithDefined(Sym, In.Plt, getPltEntryOffset(Sym.PltIndex), 0);
937 Sym.NeedsPltAddr = true;964 Sym.NeedsPltAddr = true;
938 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});965 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
939 return;966 return;
...@@ -967,7 +994,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,...@@ -967,7 +994,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
967 if (maybeReportUndefined(Sym, Sec, Rel.r_offset))994 if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
968 return;995 return;
969996
970 const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset;997 const uint8_t *RelocatedAddr = Sec.data().begin() + Rel.r_offset;
971 RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);998 RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
972999
973 // Ignore "hint" relocations because they are only markers for relaxation.1000 // Ignore "hint" relocations because they are only markers for relaxation.
...@@ -985,18 +1012,28 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,...@@ -985,18 +1012,28 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
985 // all dynamic symbols that can be resolved within the executable will1012 // all dynamic symbols that can be resolved within the executable will
986 // actually be resolved that way at runtime, because the main exectuable1013 // actually be resolved that way at runtime, because the main exectuable
987 // is always at the beginning of a search list. We can leverage that fact.1014 // is always at the beginning of a search list. We can leverage that fact.
988 if (Sym.isGnuIFunc())1015 if (Sym.isGnuIFunc()) {
1016 if (!Config->ZText && Config->WarnIfuncTextrel) {
1017 warn("using ifunc symbols when text relocations are allowed may produce "
1018 "a binary that will segfault, if the object file is linked with "
1019 "old version of glibc (glibc 2.28 and earlier). If this applies to "
1020 "you, consider recompiling the object files without -fPIC and "
1021 "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
1022 "turn off this warning." +
1023 getLocation(Sec, Sym, Offset));
1024 }
989 Expr = toPlt(Expr);1025 Expr = toPlt(Expr);
990 else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))1026 } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
991 Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);1027 Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
992 else if (!Sym.IsPreemptible)1028 } else if (!Sym.IsPreemptible) {
993 Expr = fromPlt(Expr);1029 Expr = fromPlt(Expr);
1030 }
9941031
995 // This relocation does not require got entry, but it is relative to got and1032 // This relocation does not require got entry, but it is relative to got and
996 // needs it to be created. Here we request for that.1033 // needs it to be created. Here we request for that.
997 if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,1034 if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
998 R_GOTREL_FROM_END, R_PPC_TOC>(Expr))1035 R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
999 InX::Got->HasGotOffRel = true;1036 In.Got->HasGotOffRel = true;
10001037
1001 // Read an addend.1038 // Read an addend.
1002 int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());1039 int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
...@@ -1012,11 +1049,10 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,...@@ -1012,11 +1049,10 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
1012 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.1049 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
1013 if (needsPlt(Expr) && !Sym.isInPlt()) {1050 if (needsPlt(Expr) && !Sym.isInPlt()) {
1014 if (Sym.isGnuIFunc() && !Sym.IsPreemptible)1051 if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
1015 addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,1052 addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
1016 Target->IRelativeRel, Sym);
1017 else
1018 addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
1019 Sym);1053 Sym);
1054 else
1055 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
1020 }1056 }
10211057
1022 // Create a GOT slot if a relocation needs GOT.1058 // Create a GOT slot if a relocation needs GOT.
...@@ -1029,7 +1065,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,...@@ -1029,7 +1065,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
1029 // See "Global Offset Table" in Chapter 5 in the following document1065 // See "Global Offset Table" in Chapter 5 in the following document
1030 // for detailed description:1066 // for detailed description:
1031 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf1067 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1032 InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);1068 In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
1033 } else if (!Sym.isInGot()) {1069 } else if (!Sym.isInGot()) {
1034 addGotEntry<ELFT>(Sym);1070 addGotEntry<ELFT>(Sym);
1035 }1071 }
...@@ -1047,6 +1083,11 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {...@@ -1047,6 +1083,11 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
10471083
1048 for (auto I = Rels.begin(), End = Rels.end(); I != End;)1084 for (auto I = Rels.begin(), End = Rels.end(); I != End;)
1049 scanReloc<ELFT>(Sec, GetOffset, I, End);1085 scanReloc<ELFT>(Sec, GetOffset, I, End);
1086
1087 // Sort relocations by offset to binary search for R_RISCV_PCREL_HI20
1088 if (Config->EMachine == EM_RISCV)
1089 std::stable_sort(Sec.Relocations.begin(), Sec.Relocations.end(),
1090 RelocationOffsetComparator{});
1050}1091}
10511092
1052template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {1093template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
...@@ -1056,6 +1097,43 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {...@@ -1056,6 +1097,43 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
1056 scanRelocs<ELFT>(S, S.rels<ELFT>());1097 scanRelocs<ELFT>(S, S.rels<ELFT>());
1057}1098}
10581099
1100static bool mergeCmp(const InputSection *A, const InputSection *B) {
1101 // std::merge requires a strict weak ordering.
1102 if (A->OutSecOff < B->OutSecOff)
1103 return true;
1104
1105 if (A->OutSecOff == B->OutSecOff) {
1106 auto *TA = dyn_cast<ThunkSection>(A);
1107 auto *TB = dyn_cast<ThunkSection>(B);
1108
1109 // Check if Thunk is immediately before any specific Target
1110 // InputSection for example Mips LA25 Thunks.
1111 if (TA && TA->getTargetInputSection() == B)
1112 return true;
1113
1114 // Place Thunk Sections without specific targets before
1115 // non-Thunk Sections.
1116 if (TA && !TB && !TA->getTargetInputSection())
1117 return true;
1118 }
1119
1120 return false;
1121}
1122
1123// Call Fn on every executable InputSection accessed via the linker script
1124// InputSectionDescription::Sections.
1125static void forEachInputSectionDescription(
1126 ArrayRef<OutputSection *> OutputSections,
1127 llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn) {
1128 for (OutputSection *OS : OutputSections) {
1129 if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
1130 continue;
1131 for (BaseCommand *BC : OS->SectionCommands)
1132 if (auto *ISD = dyn_cast<InputSectionDescription>(BC))
1133 Fn(OS, ISD);
1134 }
1135}
1136
1059// Thunk Implementation1137// Thunk Implementation
1060//1138//
1061// Thunks (sometimes called stubs, veneers or branch islands) are small pieces1139// Thunks (sometimes called stubs, veneers or branch islands) are small pieces
...@@ -1158,6 +1236,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {...@@ -1158,6 +1236,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
1158 [](const std::pair<ThunkSection *, uint32_t> &TS) {1236 [](const std::pair<ThunkSection *, uint32_t> &TS) {
1159 return TS.first->getSize() == 0;1237 return TS.first->getSize() == 0;
1160 });1238 });
1239
1161 // ISD->ThunkSections contains all created ThunkSections, including1240 // ISD->ThunkSections contains all created ThunkSections, including
1162 // those inserted in previous passes. Extract the Thunks created this1241 // those inserted in previous passes. Extract the Thunks created this
1163 // pass and order them in ascending OutSecOff.1242 // pass and order them in ascending OutSecOff.
...@@ -1173,27 +1252,11 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {...@@ -1173,27 +1252,11 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
1173 // Merge sorted vectors of Thunks and InputSections by OutSecOff1252 // Merge sorted vectors of Thunks and InputSections by OutSecOff
1174 std::vector<InputSection *> Tmp;1253 std::vector<InputSection *> Tmp;
1175 Tmp.reserve(ISD->Sections.size() + NewThunks.size());1254 Tmp.reserve(ISD->Sections.size() + NewThunks.size());
1176 auto MergeCmp = [](const InputSection *A, const InputSection *B) {1255
1177 // std::merge requires a strict weak ordering.
1178 if (A->OutSecOff < B->OutSecOff)
1179 return true;
1180 if (A->OutSecOff == B->OutSecOff) {
1181 auto *TA = dyn_cast<ThunkSection>(A);
1182 auto *TB = dyn_cast<ThunkSection>(B);
1183 // Check if Thunk is immediately before any specific Target
1184 // InputSection for example Mips LA25 Thunks.
1185 if (TA && TA->getTargetInputSection() == B)
1186 return true;
1187 if (TA && !TB && !TA->getTargetInputSection())
1188 // Place Thunk Sections without specific targets before
1189 // non-Thunk Sections.
1190 return true;
1191 }
1192 return false;
1193 };
1194 std::merge(ISD->Sections.begin(), ISD->Sections.end(),1256 std::merge(ISD->Sections.begin(), ISD->Sections.end(),
1195 NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),1257 NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),
1196 MergeCmp);1258 mergeCmp);
1259
1197 ISD->Sections = std::move(Tmp);1260 ISD->Sections = std::move(Tmp);
1198 });1261 });
1199}1262}
...@@ -1237,20 +1300,23 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {...@@ -1237,20 +1300,23 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
1237 // Find InputSectionRange within Target Output Section (TOS) that the1300 // Find InputSectionRange within Target Output Section (TOS) that the
1238 // InputSection (IS) that we need to precede is in.1301 // InputSection (IS) that we need to precede is in.
1239 OutputSection *TOS = IS->getParent();1302 OutputSection *TOS = IS->getParent();
1240 for (BaseCommand *BC : TOS->SectionCommands)1303 for (BaseCommand *BC : TOS->SectionCommands) {
1241 if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {1304 auto *ISD = dyn_cast<InputSectionDescription>(BC);
1242 if (ISD->Sections.empty())1305 if (!ISD || ISD->Sections.empty())
1243 continue;1306 continue;
1244 InputSection *first = ISD->Sections.front();1307
1245 InputSection *last = ISD->Sections.back();1308 InputSection *First = ISD->Sections.front();
1246 if (IS->OutSecOff >= first->OutSecOff &&1309 InputSection *Last = ISD->Sections.back();
1247 IS->OutSecOff <= last->OutSecOff) {1310
1248 TS = addThunkSection(TOS, ISD, IS->OutSecOff);1311 if (IS->OutSecOff < First->OutSecOff || Last->OutSecOff < IS->OutSecOff)
1249 ThunkedSections[IS] = TS;1312 continue;
1250 break;1313
1251 }1314 TS = addThunkSection(TOS, ISD, IS->OutSecOff);
1252 }1315 ThunkedSections[IS] = TS;
1253 return TS;1316 return TS;
1317 }
1318
1319 return nullptr;
1254}1320}
12551321
1256// Create one or more ThunkSections per OS that can be used to place Thunks.1322// Create one or more ThunkSections per OS that can be used to place Thunks.
...@@ -1271,26 +1337,29 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {...@@ -1271,26 +1337,29 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
1271// allow for the creation of a short thunk.1337// allow for the creation of a short thunk.
1272void ThunkCreator::createInitialThunkSections(1338void ThunkCreator::createInitialThunkSections(
1273 ArrayRef<OutputSection *> OutputSections) {1339 ArrayRef<OutputSection *> OutputSections) {
1340 uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
1341
1274 forEachInputSectionDescription(1342 forEachInputSectionDescription(
1275 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {1343 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
1276 if (ISD->Sections.empty())1344 if (ISD->Sections.empty())
1277 return;1345 return;
1346
1278 uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;1347 uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
1279 uint32_t ISDEnd =1348 uint32_t ISDEnd =
1280 ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();1349 ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
1281 uint32_t LastThunkLowerBound = -1;1350 uint32_t LastThunkLowerBound = -1;
1282 if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2)1351 if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
1283 LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing;1352 LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
12841353
1285 uint32_t ISLimit;1354 uint32_t ISLimit;
1286 uint32_t PrevISLimit = ISDBegin;1355 uint32_t PrevISLimit = ISDBegin;
1287 uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing;1356 uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
12881357
1289 for (const InputSection *IS : ISD->Sections) {1358 for (const InputSection *IS : ISD->Sections) {
1290 ISLimit = IS->OutSecOff + IS->getSize();1359 ISLimit = IS->OutSecOff + IS->getSize();
1291 if (ISLimit > ThunkUpperBound) {1360 if (ISLimit > ThunkUpperBound) {
1292 addThunkSection(OS, ISD, PrevISLimit);1361 addThunkSection(OS, ISD, PrevISLimit);
1293 ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;1362 ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
1294 }1363 }
1295 if (ISLimit > LastThunkLowerBound)1364 if (ISLimit > LastThunkLowerBound)
1296 break;1365 break;
...@@ -1304,13 +1373,14 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,...@@ -1304,13 +1373,14 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
1304 InputSectionDescription *ISD,1373 InputSectionDescription *ISD,
1305 uint64_t Off) {1374 uint64_t Off) {
1306 auto *TS = make<ThunkSection>(OS, Off);1375 auto *TS = make<ThunkSection>(OS, Off);
1307 ISD->ThunkSections.push_back(std::make_pair(TS, Pass));1376 ISD->ThunkSections.push_back({TS, Pass});
1308 return TS;1377 return TS;
1309}1378}
13101379
1311std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,1380std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
1312 uint64_t Src) {1381 uint64_t Src) {
1313 std::vector<Thunk *> *ThunkVec = nullptr;1382 std::vector<Thunk *> *ThunkVec = nullptr;
1383
1314 // We use (section, offset) pair to find the thunk position if possible so1384 // We use (section, offset) pair to find the thunk position if possible so
1315 // that we create only one thunk for aliased symbols or ICFed sections.1385 // that we create only one thunk for aliased symbols or ICFed sections.
1316 if (auto *D = dyn_cast<Defined>(&Sym))1386 if (auto *D = dyn_cast<Defined>(&Sym))
...@@ -1318,40 +1388,28 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,...@@ -1318,40 +1388,28 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
1318 ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];1388 ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];
1319 if (!ThunkVec)1389 if (!ThunkVec)
1320 ThunkVec = &ThunkedSymbols[&Sym];1390 ThunkVec = &ThunkedSymbols[&Sym];
1391
1321 // Check existing Thunks for Sym to see if they can be reused1392 // Check existing Thunks for Sym to see if they can be reused
1322 for (Thunk *ET : *ThunkVec)1393 for (Thunk *T : *ThunkVec)
1323 if (ET->isCompatibleWith(Type) &&1394 if (T->isCompatibleWith(Type) &&
1324 Target->inBranchRange(Type, Src, ET->getThunkTargetSym()->getVA()))1395 Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA()))
1325 return std::make_pair(ET, false);1396 return std::make_pair(T, false);
1397
1326 // No existing compatible Thunk in range, create a new one1398 // No existing compatible Thunk in range, create a new one
1327 Thunk *T = addThunk(Type, Sym);1399 Thunk *T = addThunk(Type, Sym);
1328 ThunkVec->push_back(T);1400 ThunkVec->push_back(T);
1329 return std::make_pair(T, true);1401 return std::make_pair(T, true);
1330}1402}
13311403
1332// Call Fn on every executable InputSection accessed via the linker script
1333// InputSectionDescription::Sections.
1334void ThunkCreator::forEachInputSectionDescription(
1335 ArrayRef<OutputSection *> OutputSections,
1336 llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn) {
1337 for (OutputSection *OS : OutputSections) {
1338 if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
1339 continue;
1340 for (BaseCommand *BC : OS->SectionCommands)
1341 if (auto *ISD = dyn_cast<InputSectionDescription>(BC))
1342 Fn(OS, ISD);
1343 }
1344}
1345
1346// Return true if the relocation target is an in range Thunk.1404// Return true if the relocation target is an in range Thunk.
1347// Return false if the relocation is not to a Thunk. If the relocation target1405// Return false if the relocation is not to a Thunk. If the relocation target
1348// was originally to a Thunk, but is no longer in range we revert the1406// was originally to a Thunk, but is no longer in range we revert the
1349// relocation back to its original non-Thunk target.1407// relocation back to its original non-Thunk target.
1350bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {1408bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
1351 if (Thunk *ET = Thunks.lookup(Rel.Sym)) {1409 if (Thunk *T = Thunks.lookup(Rel.Sym)) {
1352 if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))1410 if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))
1353 return true;1411 return true;
1354 Rel.Sym = &ET->Destination;1412 Rel.Sym = &T->Destination;
1355 if (Rel.Sym->isInPlt())1413 if (Rel.Sym->isInPlt())
1356 Rel.Expr = toPlt(Rel.Expr);1414 Rel.Expr = toPlt(Rel.Expr);
1357 }1415 }
...@@ -1385,11 +1443,13 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {...@@ -1385,11 +1443,13 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
1385// relocation out of range error.1443// relocation out of range error.
1386bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {1444bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
1387 bool AddressesChanged = false;1445 bool AddressesChanged = false;
1388 if (Pass == 0 && Target->ThunkSectionSpacing)1446
1447 if (Pass == 0 && Target->getThunkSectionSpacing())
1389 createInitialThunkSections(OutputSections);1448 createInitialThunkSections(OutputSections);
1390 else if (Pass == 10)1449
1391 // With Thunk Size much smaller than branch range we expect to1450 // With Thunk Size much smaller than branch range we expect to
1392 // converge quickly; if we get to 10 something has gone wrong.1451 // converge quickly; if we get to 10 something has gone wrong.
1452 if (Pass == 10)
1393 fatal("thunk creation not converged");1453 fatal("thunk creation not converged");
13941454
1395 // Create all the Thunks and insert them into synthetic ThunkSections. The1455 // Create all the Thunks and insert them into synthetic ThunkSections. The
...@@ -1412,9 +1472,11 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {...@@ -1412,9 +1472,11 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
1412 if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,1472 if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,
1413 *Rel.Sym))1473 *Rel.Sym))
1414 continue;1474 continue;
1475
1415 Thunk *T;1476 Thunk *T;
1416 bool IsNew;1477 bool IsNew;
1417 std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src);1478 std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src);
1479
1418 if (IsNew) {1480 if (IsNew) {
1419 // Find or create a ThunkSection for the new Thunk1481 // Find or create a ThunkSection for the new Thunk
1420 ThunkSection *TS;1482 ThunkSection *TS;
...@@ -1425,13 +1487,16 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {...@@ -1425,13 +1487,16 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
1425 TS->addThunk(T);1487 TS->addThunk(T);
1426 Thunks[T->getThunkTargetSym()] = T;1488 Thunks[T->getThunkTargetSym()] = T;
1427 }1489 }
1490
1428 // Redirect relocation to Thunk, we never go via the PLT to a Thunk1491 // Redirect relocation to Thunk, we never go via the PLT to a Thunk
1429 Rel.Sym = T->getThunkTargetSym();1492 Rel.Sym = T->getThunkTargetSym();
1430 Rel.Expr = fromPlt(Rel.Expr);1493 Rel.Expr = fromPlt(Rel.Expr);
1431 }1494 }
1495
1432 for (auto &P : ISD->ThunkSections)1496 for (auto &P : ISD->ThunkSections)
1433 AddressesChanged |= P.first->assignOffsets();1497 AddressesChanged |= P.first->assignOffsets();
1434 });1498 });
1499
1435 for (auto &P : ThunkedSections)1500 for (auto &P : ThunkedSections)
1436 AddressesChanged |= P.second->assignOffsets();1501 AddressesChanged |= P.second->assignOffsets();
14371502
deps/lld/ELF/Relocations.h+30-9
...@@ -33,16 +33,28 @@ enum RelExpr {...@@ -33,16 +33,28 @@ enum RelExpr {
33 R_INVALID,33 R_INVALID,
34 R_ABS,34 R_ABS,
35 R_ADDEND,35 R_ADDEND,
36 R_AARCH64_GOT_PAGE_PC,
37 // The expression is used for IFUNC support. Describes PC-relative
38 // address of the memory page of GOT entry. This entry is used for
39 // a redirection to IPLT.
40 R_AARCH64_GOT_PAGE_PC_PLT,
41 R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
42 R_AARCH64_PAGE_PC,
43 R_AARCH64_PLT_PAGE_PC,
44 R_AARCH64_TLSDESC_PAGE,
36 R_ARM_SBREL,45 R_ARM_SBREL,
37 R_GOT,46 R_GOT,
47 // The expression is used for IFUNC support. Evaluates to GOT entry,
48 // containing redirection to the IPLT.
49 R_GOT_PLT,
38 R_GOTONLY_PC,50 R_GOTONLY_PC,
39 R_GOTONLY_PC_FROM_END,51 R_GOTONLY_PC_FROM_END,
40 R_GOTREL,52 R_GOTREL,
41 R_GOTREL_FROM_END,53 R_GOTREL_FROM_END,
42 R_GOT_FROM_END,54 R_GOT_FROM_END,
43 R_GOT_OFF,55 R_GOT_OFF,
44 R_GOT_PAGE_PC,
45 R_GOT_PC,56 R_GOT_PC,
57 R_HEXAGON_GOT,
46 R_HINT,58 R_HINT,
47 R_MIPS_GOTREL,59 R_MIPS_GOTREL,
48 R_MIPS_GOT_GP,60 R_MIPS_GOT_GP,
...@@ -54,10 +66,8 @@ enum RelExpr {...@@ -54,10 +66,8 @@ enum RelExpr {
54 R_MIPS_TLSLD,66 R_MIPS_TLSLD,
55 R_NEG_TLS,67 R_NEG_TLS,
56 R_NONE,68 R_NONE,
57 R_PAGE_PC,
58 R_PC,69 R_PC,
59 R_PLT,70 R_PLT,
60 R_PLT_PAGE_PC,
61 R_PLT_PC,71 R_PLT_PC,
62 R_PPC_CALL,72 R_PPC_CALL,
63 R_PPC_CALL_PLT,73 R_PPC_CALL_PLT,
...@@ -68,20 +78,20 @@ enum RelExpr {...@@ -68,20 +78,20 @@ enum RelExpr {
68 R_RELAX_TLS_GD_TO_IE_ABS,78 R_RELAX_TLS_GD_TO_IE_ABS,
69 R_RELAX_TLS_GD_TO_IE_END,79 R_RELAX_TLS_GD_TO_IE_END,
70 R_RELAX_TLS_GD_TO_IE_GOT_OFF,80 R_RELAX_TLS_GD_TO_IE_GOT_OFF,
71 R_RELAX_TLS_GD_TO_IE_PAGE_PC,
72 R_RELAX_TLS_GD_TO_LE,81 R_RELAX_TLS_GD_TO_LE,
73 R_RELAX_TLS_GD_TO_LE_NEG,82 R_RELAX_TLS_GD_TO_LE_NEG,
74 R_RELAX_TLS_IE_TO_LE,83 R_RELAX_TLS_IE_TO_LE,
75 R_RELAX_TLS_LD_TO_LE,84 R_RELAX_TLS_LD_TO_LE,
76 R_RELAX_TLS_LD_TO_LE_ABS,85 R_RELAX_TLS_LD_TO_LE_ABS,
86 R_RISCV_PC_INDIRECT,
77 R_SIZE,87 R_SIZE,
78 R_TLS,88 R_TLS,
79 R_TLSDESC,89 R_TLSDESC,
80 R_TLSDESC_CALL,90 R_TLSDESC_CALL,
81 R_TLSDESC_PAGE,
82 R_TLSGD_GOT,91 R_TLSGD_GOT,
83 R_TLSGD_GOT_FROM_END,92 R_TLSGD_GOT_FROM_END,
84 R_TLSGD_PC,93 R_TLSGD_PC,
94 R_TLSIE_HINT,
85 R_TLSLD_GOT,95 R_TLSLD_GOT,
86 R_TLSLD_GOT_FROM_END,96 R_TLSLD_GOT_FROM_END,
87 R_TLSLD_GOT_OFF,97 R_TLSLD_GOT_OFF,
...@@ -128,6 +138,21 @@ struct Relocation {...@@ -128,6 +138,21 @@ struct Relocation {
128 Symbol *Sym;138 Symbol *Sym;
129};139};
130140
141struct RelocationOffsetComparator {
142 bool operator()(const Relocation &Lhs, const Relocation &Rhs) {
143 return Lhs.Offset < Rhs.Offset;
144 }
145
146 // For std::lower_bound, std::upper_bound, std::equal_range.
147 bool operator()(const Relocation &Rel, uint64_t Val) {
148 return Rel.Offset < Val;
149 }
150
151 bool operator()(uint64_t Val, const Relocation &Rel) {
152 return Val < Rel.Offset;
153 }
154};
155
131template <class ELFT> void scanRelocations(InputSectionBase &);156template <class ELFT> void scanRelocations(InputSectionBase &);
132157
133class ThunkSection;158class ThunkSection;
...@@ -155,10 +180,6 @@ private:...@@ -155,10 +180,6 @@ private:
155180
156 void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);181 void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
157182
158 void forEachInputSectionDescription(
159 ArrayRef<OutputSection *> OutputSections,
160 llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn);
161
162 std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src);183 std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src);
163184
164 ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,185 ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
deps/lld/ELF/ScriptLexer.cpp+9
...@@ -244,6 +244,15 @@ StringRef ScriptLexer::peek() {...@@ -244,6 +244,15 @@ StringRef ScriptLexer::peek() {
244 return Tok;244 return Tok;
245}245}
246246
247StringRef ScriptLexer::peek2() {
248 skip();
249 StringRef Tok = next();
250 if (errorCount())
251 return "";
252 Pos = Pos - 2;
253 return Tok;
254}
255
247bool ScriptLexer::consume(StringRef Tok) {256bool ScriptLexer::consume(StringRef Tok) {
248 if (peek() == Tok) {257 if (peek() == Tok) {
249 skip();258 skip();
deps/lld/ELF/ScriptLexer.h+1
...@@ -29,6 +29,7 @@ public:...@@ -29,6 +29,7 @@ public:
29 bool atEOF();29 bool atEOF();
30 StringRef next();30 StringRef next();
31 StringRef peek();31 StringRef peek();
32 StringRef peek2();
32 void skip();33 void skip();
33 bool consume(StringRef Tok);34 bool consume(StringRef Tok);
34 void expect(StringRef Expect);35 void expect(StringRef Expect);
deps/lld/ELF/ScriptParser.cpp+108-36
...@@ -72,13 +72,15 @@ private:...@@ -72,13 +72,15 @@ private:
72 void readRegionAlias();72 void readRegionAlias();
73 void readSearchDir();73 void readSearchDir();
74 void readSections();74 void readSections();
75 void readTarget();
75 void readVersion();76 void readVersion();
76 void readVersionScriptCommand();77 void readVersionScriptCommand();
7778
78 SymbolAssignment *readSymbolAssignment(StringRef Name);79 SymbolAssignment *readSymbolAssignment(StringRef Name);
79 ByteCommand *readByteCommand(StringRef Tok);80 ByteCommand *readByteCommand(StringRef Tok);
80 uint32_t readFill();81 std::array<uint8_t, 4> readFill();
81 uint32_t parseFill(StringRef Tok);82 std::array<uint8_t, 4> parseFill(StringRef Tok);
83 bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
82 void readSectionAddressType(OutputSection *Cmd);84 void readSectionAddressType(OutputSection *Cmd);
83 OutputSection *readOverlaySectionDescription();85 OutputSection *readOverlaySectionDescription();
84 OutputSection *readOutputSectionDescription(StringRef OutSec);86 OutputSection *readOutputSectionDescription(StringRef OutSec);
...@@ -255,6 +257,8 @@ void ScriptParser::readLinkerScript() {...@@ -255,6 +257,8 @@ void ScriptParser::readLinkerScript() {
255 readSearchDir();257 readSearchDir();
256 } else if (Tok == "SECTIONS") {258 } else if (Tok == "SECTIONS") {
257 readSections();259 readSections();
260 } else if (Tok == "TARGET") {
261 readTarget();
258 } else if (Tok == "VERSION") {262 } else if (Tok == "VERSION") {
259 readVersion();263 readVersion();
260 } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {264 } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
...@@ -266,6 +270,8 @@ void ScriptParser::readLinkerScript() {...@@ -266,6 +270,8 @@ void ScriptParser::readLinkerScript() {
266}270}
267271
268void ScriptParser::readDefsym(StringRef Name) {272void ScriptParser::readDefsym(StringRef Name) {
273 if (errorCount())
274 return;
269 Expr E = readExpr();275 Expr E = readExpr();
270 if (!atEOF())276 if (!atEOF())
271 setError("EOF expected, but got " + next());277 setError("EOF expected, but got " + next());
...@@ -378,10 +384,42 @@ void ScriptParser::readOutputArch() {...@@ -378,10 +384,42 @@ void ScriptParser::readOutputArch() {
378 skip();384 skip();
379}385}
380386
387static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
388 return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
389 .Case("elf32-i386", {ELF32LEKind, EM_386})
390 .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
391 .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
392 .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
393 .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
394 .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
395 .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
396 .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
397 .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
398 .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS})
399 .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
400 .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
401 .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
402 .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
403 .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
404 .Default({ELFNoneKind, EM_NONE});
405}
406
407// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
408// Currently we ignore big and little parameters.
381void ScriptParser::readOutputFormat() {409void ScriptParser::readOutputFormat() {
382 // Error checking only for now.
383 expect("(");410 expect("(");
384 skip();411
412 StringRef Name = unquote(next());
413 StringRef S = Name;
414 if (S.consume_back("-freebsd"))
415 Config->OSABI = ELFOSABI_FREEBSD;
416
417 std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
418 if (Config->EMachine == EM_NONE)
419 setError("unknown output format name: " + Name);
420 if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
421 Config->MipsN32Abi = true;
422
385 if (consume(")"))423 if (consume(")"))
386 return;424 return;
387 expect(",");425 expect(",");
...@@ -497,6 +535,9 @@ void ScriptParser::readSections() {...@@ -497,6 +535,9 @@ void ScriptParser::readSections() {
497 for (BaseCommand *Cmd : readOverlay())535 for (BaseCommand *Cmd : readOverlay())
498 V.push_back(Cmd);536 V.push_back(Cmd);
499 continue;537 continue;
538 } else if (Tok == "INCLUDE") {
539 readInclude();
540 continue;
500 }541 }
501542
502 if (BaseCommand *Cmd = readAssignment(Tok))543 if (BaseCommand *Cmd = readAssignment(Tok))
...@@ -522,6 +563,23 @@ void ScriptParser::readSections() {...@@ -522,6 +563,23 @@ void ScriptParser::readSections() {
522 V.end());563 V.end());
523}564}
524565
566void ScriptParser::readTarget() {
567 // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
568 // we accept only a limited set of BFD names (i.e. "elf" or "binary")
569 // for --format. We recognize only /^elf/ and "binary" in the linker
570 // script as well.
571 expect("(");
572 StringRef Tok = next();
573 expect(")");
574
575 if (Tok.startswith("elf"))
576 Config->FormatBinary = false;
577 else if (Tok == "binary")
578 Config->FormatBinary = true;
579 else
580 setError("unknown target: " + Tok);
581}
582
525static int precedence(StringRef Op) {583static int precedence(StringRef Op) {
526 return StringSwitch<int>(Op)584 return StringSwitch<int>(Op)
527 .Cases("*", "/", "%", 8)585 .Cases("*", "/", "%", 8)
...@@ -672,13 +730,33 @@ Expr ScriptParser::readAssert() {...@@ -672,13 +730,33 @@ Expr ScriptParser::readAssert() {
672// alias for =fillexp section attribute, which is different from730// alias for =fillexp section attribute, which is different from
673// what GNU linkers do.731// what GNU linkers do.
674// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html732// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
675uint32_t ScriptParser::readFill() {733std::array<uint8_t, 4> ScriptParser::readFill() {
676 expect("(");734 expect("(");
677 uint32_t V = parseFill(next());735 std::array<uint8_t, 4> V = parseFill(next());
678 expect(")");736 expect(")");
679 return V;737 return V;
680}738}
681739
740// Tries to read the special directive for an output section definition which
741// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
742// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
743bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
744 if (Tok1 != "(")
745 return false;
746 if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
747 return false;
748
749 expect("(");
750 if (consume("NOLOAD")) {
751 Cmd->Noload = true;
752 } else {
753 skip(); // This is "COPY", "INFO" or "OVERLAY".
754 Cmd->NonAlloc = true;
755 }
756 expect(")");
757 return true;
758}
759
682// Reads an expression and/or the special directive for an output760// Reads an expression and/or the special directive for an output
683// section definition. Directive is one of following: "(NOLOAD)",761// section definition. Directive is one of following: "(NOLOAD)",
684// "(COPY)", "(INFO)" or "(OVERLAY)".762// "(COPY)", "(INFO)" or "(OVERLAY)".
...@@ -691,28 +769,12 @@ uint32_t ScriptParser::readFill() {...@@ -691,28 +769,12 @@ uint32_t ScriptParser::readFill() {
691// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html769// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
692// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html770// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
693void ScriptParser::readSectionAddressType(OutputSection *Cmd) {771void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
694 if (consume("(")) {772 if (readSectionDirective(Cmd, peek(), peek2()))
695 if (consume("NOLOAD")) {773 return;
696 expect(")");
697 Cmd->Noload = true;
698 return;
699 }
700 if (consume("COPY") || consume("INFO") || consume("OVERLAY")) {
701 expect(")");
702 Cmd->NonAlloc = true;
703 return;
704 }
705 Cmd->AddrExpr = readExpr();
706 expect(")");
707 } else {
708 Cmd->AddrExpr = readExpr();
709 }
710774
711 if (consume("(")) {775 Cmd->AddrExpr = readExpr();
712 expect("NOLOAD");776 if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
713 expect(")");777 setError("unknown section directive: " + peek2());
714 Cmd->Noload = true;
715 }
716}778}
717779
718static Expr checkAlignment(Expr E, std::string &Loc) {780static Expr checkAlignment(Expr E, std::string &Loc) {
...@@ -778,10 +840,17 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {...@@ -778,10 +840,17 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
778 Cmd->Filler = readFill();840 Cmd->Filler = readFill();
779 } else if (Tok == "SORT") {841 } else if (Tok == "SORT") {
780 readSort();842 readSort();
843 } else if (Tok == "INCLUDE") {
844 readInclude();
781 } else if (peek() == "(") {845 } else if (peek() == "(") {
782 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));846 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
783 } else {847 } else {
784 setError("unknown command " + Tok);848 // We have a file name and no input sections description. It is not a
849 // commonly used syntax, but still acceptable. In that case, all sections
850 // from the file will be included.
851 auto *ISD = make<InputSectionDescription>(Tok);
852 ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})});
853 Cmd->SectionCommands.push_back(ISD);
785 }854 }
786 }855 }
787856
...@@ -818,13 +887,13 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {...@@ -818,13 +887,13 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
818// When reading a hexstring, ld.bfd handles it as a blob of arbitrary887// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
819// size, while ld.gold always handles it as a 32-bit big-endian number.888// size, while ld.gold always handles it as a 32-bit big-endian number.
820// We are compatible with ld.gold because it's easier to implement.889// We are compatible with ld.gold because it's easier to implement.
821uint32_t ScriptParser::parseFill(StringRef Tok) {890std::array<uint8_t, 4> ScriptParser::parseFill(StringRef Tok) {
822 uint32_t V = 0;891 uint32_t V = 0;
823 if (!to_integer(Tok, V))892 if (!to_integer(Tok, V))
824 setError("invalid filler expression: " + Tok);893 setError("invalid filler expression: " + Tok);
825894
826 uint32_t Buf;895 std::array<uint8_t, 4> Buf;
827 write32be(&Buf, V);896 write32be(Buf.data(), V);
828 return Buf;897 return Buf;
829}898}
830899
...@@ -1404,7 +1473,11 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,...@@ -1404,7 +1473,11 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
1404void ScriptParser::readMemory() {1473void ScriptParser::readMemory() {
1405 expect("{");1474 expect("{");
1406 while (!errorCount() && !consume("}")) {1475 while (!errorCount() && !consume("}")) {
1407 StringRef Name = next();1476 StringRef Tok = next();
1477 if (Tok == "INCLUDE") {
1478 readInclude();
1479 continue;
1480 }
14081481
1409 uint32_t Flags = 0;1482 uint32_t Flags = 0;
1410 uint32_t NegFlags = 0;1483 uint32_t NegFlags = 0;
...@@ -1419,10 +1492,9 @@ void ScriptParser::readMemory() {...@@ -1419,10 +1492,9 @@ void ScriptParser::readMemory() {
1419 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");1492 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
14201493
1421 // Add the memory region to the region map.1494 // Add the memory region to the region map.
1422 MemoryRegion *MR =1495 MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
1423 make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags);1496 if (!Script->MemoryRegions.insert({Tok, MR}).second)
1424 if (!Script->MemoryRegions.insert({Name, MR}).second)1497 setError("region '" + Tok + "' already defined");
1425 setError("region '" + Name + "' already defined");
1426 }1498 }
1427}1499}
14281500
deps/lld/ELF/SymbolTable.cpp+92-158
...@@ -94,8 +94,20 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {...@@ -94,8 +94,20 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
94 if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {94 if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95 // DSOs are uniquified not by filename but by soname.95 // DSOs are uniquified not by filename but by soname.
96 F->parseSoName();96 F->parseSoName();
97 if (errorCount() || !SoNames.insert(F->SoName).second)97 if (errorCount())
98 return;98 return;
99
100 // If a DSO appears more than once on the command line with and without
101 // --as-needed, --no-as-needed takes precedence over --as-needed because a
102 // user can add an extra DSO with --no-as-needed to force it to be added to
103 // the dependency list.
104 DenseMap<StringRef, InputFile *>::iterator It;
105 bool WasInserted;
106 std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
107 cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
108 if (!WasInserted)
109 return;
110
99 SharedFiles.push_back(F);111 SharedFiles.push_back(F);
100 F->parseRest();112 F->parseRest();
101 return;113 return;
...@@ -139,77 +151,27 @@ template <class ELFT> void SymbolTable::addCombinedLTOObject() {...@@ -139,77 +151,27 @@ template <class ELFT> void SymbolTable::addCombinedLTOObject() {
139 }151 }
140}152}
141153
142Defined *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility,
143 uint8_t Binding) {
144 Symbol *Sym =
145 addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr);
146 return cast<Defined>(Sym);
147}
148
149// Set a flag for --trace-symbol so that we can print out a log message154// Set a flag for --trace-symbol so that we can print out a log message
150// if a new symbol with the same name is inserted into the symbol table.155// if a new symbol with the same name is inserted into the symbol table.
151void SymbolTable::trace(StringRef Name) {156void SymbolTable::trace(StringRef Name) {
152 SymMap.insert({CachedHashStringRef(Name), -1});157 SymMap.insert({CachedHashStringRef(Name), -1});
153}158}
154159
155// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.160void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
156// Used to implement --wrap.161 // Swap symbols as instructed by -wrap.
157template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {162 int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
158 Symbol *Sym = find(Name);163 int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
159 if (!Sym)164 int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
160 return;
161
162 // Do not wrap the same symbol twice.
163 for (const WrappedSymbol &S : WrappedSymbols)
164 if (S.Sym == Sym)
165 return;
166165
167 Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));166 Idx2 = Idx1;
168 Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));167 Idx1 = Idx3;
169 WrappedSymbols.push_back({Sym, Real, Wrap});
170168
171 // We want to tell LTO not to inline symbols to be overwritten169 // Now renaming is complete. No one refers Real symbol. We could leave
172 // because LTO doesn't know the final symbol contents after renaming.170 // Real as-is, but if Real is written to the symbol table, that may
173 Real->CanInline = false;171 // contain irrelevant values. So, we copy all values from Sym to Real.
174 Sym->CanInline = false;172 StringRef S = Real->getName();
175173 memcpy(Real, Sym, sizeof(SymbolUnion));
176 // Tell LTO not to eliminate these symbols.174 Real->setName(S);
177 Sym->IsUsedInRegularObj = true;
178 Wrap->IsUsedInRegularObj = true;
179}
180
181// Apply symbol renames created by -wrap. The renames are created
182// before LTO in addSymbolWrap() to have a chance to inform LTO (if
183// LTO is running) not to include these symbols in IPO. Now that the
184// symbols are finalized, we can perform the replacement.
185void SymbolTable::applySymbolWrap() {
186 // This function rotates 3 symbols:
187 //
188 // __real_sym becomes sym
189 // sym becomes __wrap_sym
190 // __wrap_sym becomes __real_sym
191 //
192 // The last part is special in that we don't want to change what references to
193 // __wrap_sym point to, we just want have __real_sym in the symbol table.
194
195 for (WrappedSymbol &W : WrappedSymbols) {
196 // First, make a copy of __real_sym.
197 Symbol *Real = nullptr;
198 if (W.Real->isDefined()) {
199 Real = reinterpret_cast<Symbol *>(make<SymbolUnion>());
200 memcpy(Real, W.Real, sizeof(SymbolUnion));
201 }
202
203 // Replace __real_sym with sym and sym with __wrap_sym.
204 memcpy(W.Real, W.Sym, sizeof(SymbolUnion));
205 memcpy(W.Sym, W.Wrap, sizeof(SymbolUnion));
206
207 // We now have two copies of __wrap_sym. Drop one.
208 W.Wrap->IsUsedInRegularObj = false;
209
210 if (Real)
211 SymVector.push_back(Real);
212 }
213}175}
214176
215static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {177static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
...@@ -221,7 +183,7 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {...@@ -221,7 +183,7 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
221}183}
222184
223// Find an existing symbol or create and insert a new one.185// Find an existing symbol or create and insert a new one.
224std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {186std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
225 // <name>@@<version> means the symbol is the default version. In that187 // <name>@@<version> means the symbol is the default version. In that
226 // case <name>@@<version> will be used to resolve references to <name>.188 // case <name>@@<version> will be used to resolve references to <name>.
227 //189 //
...@@ -239,34 +201,34 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {...@@ -239,34 +201,34 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
239201
240 if (SymIndex == -1) {202 if (SymIndex == -1) {
241 SymIndex = SymVector.size();203 SymIndex = SymVector.size();
242 IsNew = Traced = true;204 IsNew = true;
205 Traced = true;
243 }206 }
244207
245 Symbol *Sym;208 if (!IsNew)
246 if (IsNew) {209 return {SymVector[SymIndex], false};
247 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());210
248 Sym->Visibility = STV_DEFAULT;211 auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
249 Sym->IsUsedInRegularObj = false;212 Sym->SymbolKind = Symbol::PlaceholderKind;
250 Sym->ExportDynamic = false;213 Sym->Visibility = STV_DEFAULT;
251 Sym->CanInline = true;214 Sym->IsUsedInRegularObj = false;
252 Sym->Traced = Traced;215 Sym->ExportDynamic = false;
253 Sym->VersionId = Config->DefaultSymbolVersion;216 Sym->CanInline = true;
254 SymVector.push_back(Sym);217 Sym->Traced = Traced;
255 } else {218 Sym->VersionId = Config->DefaultSymbolVersion;
256 Sym = SymVector[SymIndex];219 SymVector.push_back(Sym);
257 }220 return {Sym, true};
258 return {Sym, IsNew};
259}221}
260222
261// Find an existing symbol or create and insert a new one, then apply the given223// Find an existing symbol or create and insert a new one, then apply the given
262// attributes.224// attributes.
263std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,225std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
264 uint8_t Visibility,226 uint8_t Visibility,
265 bool CanOmitFromDynSym,227 bool CanOmitFromDynSym,
266 InputFile *File) {228 InputFile *File) {
267 Symbol *S;229 Symbol *S;
268 bool WasInserted;230 bool WasInserted;
269 std::tie(S, WasInserted) = insert(Name);231 std::tie(S, WasInserted) = insertName(Name);
270232
271 // Merge in the new symbol's visibility.233 // Merge in the new symbol's visibility.
272 S->Visibility = getMinVisibility(S->Visibility, Visibility);234 S->Visibility = getMinVisibility(S->Visibility, Visibility);
...@@ -277,21 +239,9 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,...@@ -277,21 +239,9 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
277 if (!File || File->kind() == InputFile::ObjKind)239 if (!File || File->kind() == InputFile::ObjKind)
278 S->IsUsedInRegularObj = true;240 S->IsUsedInRegularObj = true;
279241
280 if (!WasInserted && S->Type != Symbol::UnknownType &&
281 ((Type == STT_TLS) != S->isTls())) {
282 error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
283 toString(S->File) + "\n>>> defined in " + toString(File));
284 }
285
286 return {S, WasInserted};242 return {S, WasInserted};
287}243}
288244
289template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
290 return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT,
291 /*Type*/ 0,
292 /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
293}
294
295static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }245static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
296246
297template <class ELFT>247template <class ELFT>
...@@ -301,8 +251,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,...@@ -301,8 +251,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
301 Symbol *S;251 Symbol *S;
302 bool WasInserted;252 bool WasInserted;
303 uint8_t Visibility = getVisibility(StOther);253 uint8_t Visibility = getVisibility(StOther);
304 std::tie(S, WasInserted) =254 std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
305 insert(Name, Type, Visibility, CanOmitFromDynSym, File);
306255
307 // An undefined symbol with non default visibility must be satisfied256 // An undefined symbol with non default visibility must be satisfied
308 // in the same DSO.257 // in the same DSO.
...@@ -314,10 +263,6 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,...@@ -314,10 +263,6 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
314 if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))263 if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
315 S->Binding = Binding;264 S->Binding = Binding;
316265
317 if (!Config->GcSections && Binding != STB_WEAK)
318 if (auto *SS = dyn_cast<SharedSymbol>(S))
319 SS->getFile<ELFT>().IsNeeded = true;
320
321 if (S->isLazy()) {266 if (S->isLazy()) {
322 // An undefined weak will not fetch archive members. See comment on Lazy in267 // An undefined weak will not fetch archive members. See comment on Lazy in
323 // Symbols.h for the details.268 // Symbols.h for the details.
...@@ -450,7 +395,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,...@@ -450,7 +395,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
450 InputFile &File) {395 InputFile &File) {
451 Symbol *S;396 Symbol *S;
452 bool WasInserted;397 bool WasInserted;
453 std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),398 std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
454 /*CanOmitFromDynSym*/ false, &File);399 /*CanOmitFromDynSym*/ false, &File);
455400
456 int Cmp = compareDefined(S, WasInserted, Binding, N);401 int Cmp = compareDefined(S, WasInserted, Binding, N);
...@@ -487,12 +432,6 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,...@@ -487,12 +432,6 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
487 return S;432 return S;
488}433}
489434
490static void reportDuplicate(Symbol *Sym, InputFile *NewFile) {
491 if (!Config->AllowMultipleDefinition)
492 error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
493 toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
494}
495
496static void reportDuplicate(Symbol *Sym, InputFile *NewFile,435static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
497 InputSectionBase *ErrSec, uint64_t ErrOffset) {436 InputSectionBase *ErrSec, uint64_t ErrOffset) {
498 if (Config->AllowMultipleDefinition)437 if (Config->AllowMultipleDefinition)
...@@ -500,7 +439,8 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,...@@ -500,7 +439,8 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
500439
501 Defined *D = cast<Defined>(Sym);440 Defined *D = cast<Defined>(Sym);
502 if (!D->Section || !ErrSec) {441 if (!D->Section || !ErrSec) {
503 reportDuplicate(Sym, NewFile);442 error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
443 toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
504 return;444 return;
505 }445 }
506446
...@@ -527,12 +467,12 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,...@@ -527,12 +467,12 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
527 error(Msg);467 error(Msg);
528}468}
529469
530Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,470Defined *SymbolTable::addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
531 uint64_t Value, uint64_t Size, uint8_t Binding,471 uint64_t Value, uint64_t Size, uint8_t Binding,
532 SectionBase *Section, InputFile *File) {472 SectionBase *Section, InputFile *File) {
533 Symbol *S;473 Symbol *S;
534 bool WasInserted;474 bool WasInserted;
535 std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),475 std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
536 /*CanOmitFromDynSym*/ false, File);476 /*CanOmitFromDynSym*/ false, File);
537 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,477 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
538 Value, Name);478 Value, Name);
...@@ -542,7 +482,7 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,...@@ -542,7 +482,7 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
542 else if (Cmp == 0)482 else if (Cmp == 0)
543 reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),483 reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
544 Value);484 Value);
545 return S;485 return cast<Defined>(S);
546}486}
547487
548template <typename ELFT>488template <typename ELFT>
...@@ -554,7 +494,7 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,...@@ -554,7 +494,7 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
554 // unchanged.494 // unchanged.
555 Symbol *S;495 Symbol *S;
556 bool WasInserted;496 bool WasInserted;
557 std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,497 std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
558 /*CanOmitFromDynSym*/ true, &File);498 /*CanOmitFromDynSym*/ true, &File);
559 // Make sure we preempt DSO symbols with default visibility.499 // Make sure we preempt DSO symbols with default visibility.
560 if (Sym.getVisibility() == STV_DEFAULT)500 if (Sym.getVisibility() == STV_DEFAULT)
...@@ -562,19 +502,16 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,...@@ -562,19 +502,16 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
562502
563 // An undefined symbol with non default visibility must be satisfied503 // An undefined symbol with non default visibility must be satisfied
564 // in the same DSO.504 // in the same DSO.
565 if (WasInserted ||505 auto Replace = [&](uint8_t Binding) {
566 ((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) {506 replaceSymbol<SharedSymbol>(S, File, Name, Binding, Sym.st_other,
567 uint8_t Binding = S->Binding;
568 bool WasUndefined = S->isUndefined();
569 replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
570 Sym.getType(), Sym.st_value, Sym.st_size,507 Sym.getType(), Sym.st_value, Sym.st_size,
571 Alignment, VerdefIndex);508 Alignment, VerdefIndex);
572 if (!WasInserted) {509 };
573 S->Binding = Binding;510
574 if (!S->isWeak() && !Config->GcSections && WasUndefined)511 if (WasInserted)
575 File.IsNeeded = true;512 Replace(Sym.getBinding());
576 }513 else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
577 }514 Replace(S->Binding);
578}515}
579516
580Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,517Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
...@@ -583,13 +520,13 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,...@@ -583,13 +520,13 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
583 Symbol *S;520 Symbol *S;
584 bool WasInserted;521 bool WasInserted;
585 std::tie(S, WasInserted) =522 std::tie(S, WasInserted) =
586 insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);523 insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
587 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,524 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
588 /*IsAbs*/ false, /*Value*/ 0, Name);525 /*IsAbs*/ false, /*Value*/ 0, Name);
589 if (Cmp > 0)526 if (Cmp > 0)
590 replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);527 replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
591 else if (Cmp == 0)528 else if (Cmp == 0)
592 reportDuplicate(S, &F);529 reportDuplicate(S, &F, nullptr, 0);
593 return S;530 return S;
594}531}
595532
...@@ -602,18 +539,14 @@ Symbol *SymbolTable::find(StringRef Name) {...@@ -602,18 +539,14 @@ Symbol *SymbolTable::find(StringRef Name) {
602 return SymVector[It->second];539 return SymVector[It->second];
603}540}
604541
605// This is used to handle lazy symbols. May replace existent542template <class ELFT>
606// symbol with lazy version or request to Fetch it.543void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
607template <class ELFT, typename LazyT, typename... ArgT>544 const object::Archive::Symbol Sym) {
608static void replaceOrFetchLazy(StringRef Name, InputFile &File,
609 llvm::function_ref<InputFile *()> Fetch,
610 ArgT &&... Arg) {
611 Symbol *S;545 Symbol *S;
612 bool WasInserted;546 bool WasInserted;
613 std::tie(S, WasInserted) = Symtab->insert(Name);547 std::tie(S, WasInserted) = insertName(Name);
614 if (WasInserted) {548 if (WasInserted) {
615 replaceSymbol<LazyT>(S, File, Symbol::UnknownType,549 replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
616 std::forward<ArgT>(Arg)...);
617 return;550 return;
618 }551 }
619 if (!S->isUndefined())552 if (!S->isUndefined())
...@@ -622,26 +555,37 @@ static void replaceOrFetchLazy(StringRef Name, InputFile &File,...@@ -622,26 +555,37 @@ static void replaceOrFetchLazy(StringRef Name, InputFile &File,
622 // An undefined weak will not fetch archive members. See comment on Lazy in555 // An undefined weak will not fetch archive members. See comment on Lazy in
623 // Symbols.h for the details.556 // Symbols.h for the details.
624 if (S->isWeak()) {557 if (S->isWeak()) {
625 replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);558 replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
626 S->Binding = STB_WEAK;559 S->Binding = STB_WEAK;
627 return;560 return;
628 }561 }
629562
630 if (InputFile *F = Fetch())563 if (InputFile *F = File.fetch(Sym))
631 Symtab->addFile<ELFT>(F);564 addFile<ELFT>(F);
632}565}
633566
634template <class ELFT>567template <class ELFT>
635void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F,568void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
636 const object::Archive::Symbol Sym) {569 Symbol *S;
637 replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },570 bool WasInserted;
638 Sym);571 std::tie(S, WasInserted) = insertName(Name);
639}572 if (WasInserted) {
573 replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
574 return;
575 }
576 if (!S->isUndefined())
577 return;
640578
641template <class ELFT>579 // An undefined weak will not fetch archive members. See comment on Lazy in
642void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {580 // Symbols.h for the details.
643 replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },581 if (S->isWeak()) {
644 Name);582 replaceSymbol<LazyObject>(S, File, S->Type, Name);
583 S->Binding = STB_WEAK;
584 return;
585 }
586
587 if (InputFile *F = File.fetch())
588 addFile<ELFT>(F);
645}589}
646590
647template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {591template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
...@@ -822,16 +766,6 @@ template void SymbolTable::addFile<ELF32BE>(InputFile *);...@@ -822,16 +766,6 @@ template void SymbolTable::addFile<ELF32BE>(InputFile *);
822template void SymbolTable::addFile<ELF64LE>(InputFile *);766template void SymbolTable::addFile<ELF64LE>(InputFile *);
823template void SymbolTable::addFile<ELF64BE>(InputFile *);767template void SymbolTable::addFile<ELF64BE>(InputFile *);
824768
825template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef);
826template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef);
827template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef);
828template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef);
829
830template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
831template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
832template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
833template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef);
834
835template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,769template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
836 uint8_t, bool, InputFile *);770 uint8_t, bool, InputFile *);
837template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,771template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
deps/lld/ELF/SymbolTable.h+10-24
...@@ -37,22 +37,17 @@ class SymbolTable {...@@ -37,22 +37,17 @@ class SymbolTable {
37public:37public:
38 template <class ELFT> void addFile(InputFile *File);38 template <class ELFT> void addFile(InputFile *File);
39 template <class ELFT> void addCombinedLTOObject();39 template <class ELFT> void addCombinedLTOObject();
40 template <class ELFT> void addSymbolWrap(StringRef Name);40 void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
41 void applySymbolWrap();
4241
43 ArrayRef<Symbol *> getSymbols() const { return SymVector; }42 ArrayRef<Symbol *> getSymbols() const { return SymVector; }
4443
45 Defined *addAbsolute(StringRef Name,
46 uint8_t Visibility = llvm::ELF::STV_HIDDEN,
47 uint8_t Binding = llvm::ELF::STB_GLOBAL);
48
49 template <class ELFT> Symbol *addUndefined(StringRef Name);
50 template <class ELFT>44 template <class ELFT>
51 Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,45 Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
52 uint8_t Type, bool CanOmitFromDynSym, InputFile *File);46 uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
53 Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,47
54 uint64_t Value, uint64_t Size, uint8_t Binding,48 Defined *addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
55 SectionBase *Section, InputFile *File);49 uint64_t Value, uint64_t Size, uint8_t Binding,
50 SectionBase *Section, InputFile *File);
5651
57 template <class ELFT>52 template <class ELFT>
58 void addShared(StringRef Name, SharedFile<ELFT> &F,53 void addShared(StringRef Name, SharedFile<ELFT> &F,
...@@ -72,10 +67,8 @@ public:...@@ -72,10 +67,8 @@ public:
72 uint8_t Binding, uint8_t StOther, uint8_t Type,67 uint8_t Binding, uint8_t StOther, uint8_t Type,
73 InputFile &File);68 InputFile &File);
7469
75 std::pair<Symbol *, bool> insert(StringRef Name);70 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
76 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,71 bool CanOmitFromDynSym, InputFile *File);
77 uint8_t Visibility, bool CanOmitFromDynSym,
78 InputFile *File);
7972
80 template <class ELFT> void fetchLazy(Symbol *Sym);73 template <class ELFT> void fetchLazy(Symbol *Sym);
8174
...@@ -88,6 +81,8 @@ public:...@@ -88,6 +81,8 @@ public:
88 void handleDynamicList();81 void handleDynamicList();
8982
90private:83private:
84 std::pair<Symbol *, bool> insertName(StringRef Name);
85
91 std::vector<Symbol *> findByVersion(SymbolVersion Ver);86 std::vector<Symbol *> findByVersion(SymbolVersion Ver);
92 std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);87 std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
9388
...@@ -113,7 +108,7 @@ private:...@@ -113,7 +108,7 @@ private:
113 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;108 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
114109
115 // Set of .so files to not link the same shared object file more than once.110 // Set of .so files to not link the same shared object file more than once.
116 llvm::DenseSet<StringRef> SoNames;111 llvm::DenseMap<StringRef, InputFile *> SoNames;
117112
118 // A map from demangled symbol names to their symbol objects.113 // A map from demangled symbol names to their symbol objects.
119 // This mapping is 1:N because two symbols with different versions114 // This mapping is 1:N because two symbols with different versions
...@@ -121,15 +116,6 @@ private:...@@ -121,15 +116,6 @@ private:
121 // directive in version scripts.116 // directive in version scripts.
122 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;117 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
123118
124 struct WrappedSymbol {
125 Symbol *Sym;
126 Symbol *Real;
127 Symbol *Wrap;
128 };
129
130 // For -wrap.
131 std::vector<WrappedSymbol> WrappedSymbols;
132
133 // For LTO.119 // For LTO.
134 std::unique_ptr<BitcodeCompiler> LTO;120 std::unique_ptr<BitcodeCompiler> LTO;
135};121};
deps/lld/ELF/Symbols.cpp+46-14
...@@ -38,6 +38,7 @@ Defined *ElfSym::GlobalOffsetTable;...@@ -38,6 +38,7 @@ Defined *ElfSym::GlobalOffsetTable;
38Defined *ElfSym::MipsGp;38Defined *ElfSym::MipsGp;
39Defined *ElfSym::MipsGpDisp;39Defined *ElfSym::MipsGpDisp;
40Defined *ElfSym::MipsLocalGp;40Defined *ElfSym::MipsLocalGp;
41Defined *ElfSym::RelaIpltStart;
41Defined *ElfSym::RelaIpltEnd;42Defined *ElfSym::RelaIpltEnd;
4243
43static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {44static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
...@@ -90,10 +91,15 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {...@@ -90,10 +91,15 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
90 uint64_t VA = IS->getVA(Offset);91 uint64_t VA = IS->getVA(Offset);
9192
92 if (D.isTls() && !Config->Relocatable) {93 if (D.isTls() && !Config->Relocatable) {
93 if (!Out::TlsPhdr)94 // Use the address of the TLS segment's first section rather than the
95 // segment's address, because segment addresses aren't initialized until
96 // after sections are finalized. (e.g. Measuring the size of .rela.dyn
97 // for Android relocation packing requires knowing TLS symbol addresses
98 // during section finalization.)
99 if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec)
94 fatal(toString(D.File) +100 fatal(toString(D.File) +
95 " has an STT_TLS symbol but doesn't have an SHF_TLS section");101 " has an STT_TLS symbol but doesn't have an SHF_TLS section");
96 return VA - Out::TlsPhdr->p_vaddr;102 return VA - Out::TlsPhdr->FirstSec->Addr;
97 }103 }
98 return VA;104 return VA;
99 }105 }
...@@ -102,7 +108,10 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {...@@ -102,7 +108,10 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
102 return 0;108 return 0;
103 case Symbol::LazyArchiveKind:109 case Symbol::LazyArchiveKind:
104 case Symbol::LazyObjectKind:110 case Symbol::LazyObjectKind:
105 llvm_unreachable("lazy symbol reached writer");111 assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
112 return 0;
113 case Symbol::PlaceholderKind:
114 llvm_unreachable("placeholder symbol reached writer");
106 }115 }
107 llvm_unreachable("invalid symbol kind");116 llvm_unreachable("invalid symbol kind");
108}117}
...@@ -112,7 +121,7 @@ uint64_t Symbol::getVA(int64_t Addend) const {...@@ -112,7 +121,7 @@ uint64_t Symbol::getVA(int64_t Addend) const {
112 return OutVA + Addend;121 return OutVA + Addend;
113}122}
114123
115uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); }124uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
116125
117uint64_t Symbol::getGotOffset() const {126uint64_t Symbol::getGotOffset() const {
118 return GotIndex * Target->GotEntrySize;127 return GotIndex * Target->GotEntrySize;
...@@ -120,8 +129,8 @@ uint64_t Symbol::getGotOffset() const {...@@ -120,8 +129,8 @@ uint64_t Symbol::getGotOffset() const {
120129
121uint64_t Symbol::getGotPltVA() const {130uint64_t Symbol::getGotPltVA() const {
122 if (this->IsInIgot)131 if (this->IsInIgot)
123 return InX::IgotPlt->getVA() + getGotPltOffset();132 return In.IgotPlt->getVA() + getGotPltOffset();
124 return InX::GotPlt->getVA() + getGotPltOffset();133 return In.GotPlt->getVA() + getGotPltOffset();
125}134}
126135
127uint64_t Symbol::getGotPltOffset() const {136uint64_t Symbol::getGotPltOffset() const {
...@@ -130,15 +139,20 @@ uint64_t Symbol::getGotPltOffset() const {...@@ -130,15 +139,20 @@ uint64_t Symbol::getGotPltOffset() const {
130 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;139 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
131}140}
132141
142uint64_t Symbol::getPPC64LongBranchOffset() const {
143 assert(PPC64BranchltIndex != 0xffff);
144 return PPC64BranchltIndex * Target->GotPltEntrySize;
145}
146
133uint64_t Symbol::getPltVA() const {147uint64_t Symbol::getPltVA() const {
134 if (this->IsInIplt)148 PltSection *Plt = IsInIplt ? In.Iplt : In.Plt;
135 return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize;149 return Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;
136 return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex);
137}150}
138151
139uint64_t Symbol::getPltOffset() const {152uint64_t Symbol::getPPC64LongBranchTableVA() const {
140 assert(!this->IsInIplt);153 assert(PPC64BranchltIndex != 0xffff);
141 return Target->getPltEntryOffset(PltIndex);154 return In.PPC64LongBranchTarget->getVA() +
155 PPC64BranchltIndex * Target->GotPltEntrySize;
142}156}
143157
144uint64_t Symbol::getSize() const {158uint64_t Symbol::getSize() const {
...@@ -204,12 +218,21 @@ void Symbol::parseSymbolVersion() {...@@ -204,12 +218,21 @@ void Symbol::parseSymbolVersion() {
204218
205InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }219InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }
206220
221MemoryBufferRef LazyArchive::getMemberBuffer() {
222 Archive::Child C = CHECK(
223 Sym.getMember(), "could not get the member for symbol " + Sym.getName());
224
225 return CHECK(C.getMemoryBufferRef(),
226 "could not get the buffer for the member defining symbol " +
227 Sym.getName());
228}
229
207uint8_t Symbol::computeBinding() const {230uint8_t Symbol::computeBinding() const {
208 if (Config->Relocatable)231 if (Config->Relocatable)
209 return Binding;232 return Binding;
210 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)233 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
211 return STB_LOCAL;234 return STB_LOCAL;
212 if (VersionId == VER_NDX_LOCAL && isDefined())235 if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
213 return STB_LOCAL;236 return STB_LOCAL;
214 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)237 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
215 return STB_GLOBAL;238 return STB_GLOBAL;
...@@ -243,10 +266,19 @@ void elf::printTraceSymbol(Symbol *Sym) {...@@ -243,10 +266,19 @@ void elf::printTraceSymbol(Symbol *Sym) {
243 message(toString(Sym->File) + S + Sym->getName());266 message(toString(Sym->File) + S + Sym->getName());
244}267}
245268
246void elf::warnUnorderableSymbol(const Symbol *Sym) {269void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
247 if (!Config->WarnSymbolOrdering)270 if (!Config->WarnSymbolOrdering)
248 return;271 return;
249272
273 // If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning
274 // is emitted. It makes sense to not warn on undefined symbols.
275 //
276 // Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols,
277 // but we don't have to be compatible here.
278 if (Sym->isUndefined() &&
279 Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
280 return;
281
250 const InputFile *File = Sym->File;282 const InputFile *File = Sym->File;
251 auto *D = dyn_cast<Defined>(Sym);283 auto *D = dyn_cast<Defined>(Sym);
252284
deps/lld/ELF/Symbols.h+51-15
...@@ -21,6 +21,14 @@...@@ -21,6 +21,14 @@
21#include "llvm/Object/ELF.h"21#include "llvm/Object/ELF.h"
2222
23namespace lld {23namespace lld {
24namespace elf {
25class Symbol;
26class InputFile;
27} // namespace elf
28
29std::string toString(const elf::Symbol &);
30std::string toString(const elf::InputFile *);
31
24namespace elf {32namespace elf {
2533
26class ArchiveFile;34class ArchiveFile;
...@@ -50,6 +58,7 @@ struct StringRefZ {...@@ -50,6 +58,7 @@ struct StringRefZ {
50class Symbol {58class Symbol {
51public:59public:
52 enum Kind {60 enum Kind {
61 PlaceholderKind,
53 DefinedKind,62 DefinedKind,
54 SharedKind,63 SharedKind,
55 UndefinedKind,64 UndefinedKind,
...@@ -70,6 +79,7 @@ public:...@@ -70,6 +79,7 @@ public:
70 uint32_t DynsymIndex = 0;79 uint32_t DynsymIndex = 0;
71 uint32_t GotIndex = -1;80 uint32_t GotIndex = -1;
72 uint32_t PltIndex = -1;81 uint32_t PltIndex = -1;
82
73 uint32_t GlobalDynIndex = -1;83 uint32_t GlobalDynIndex = -1;
7484
75 // This field is a index to the symbol's version definition.85 // This field is a index to the symbol's version definition.
...@@ -78,6 +88,9 @@ public:...@@ -78,6 +88,9 @@ public:
78 // Version definition index.88 // Version definition index.
79 uint16_t VersionId;89 uint16_t VersionId;
8090
91 // An index into the .branch_lt section on PPC64.
92 uint16_t PPC64BranchltIndex = -1;
93
81 // Symbol binding. This is not overwritten by replaceSymbol to track94 // Symbol binding. This is not overwritten by replaceSymbol to track
82 // changes during resolution. In particular:95 // changes during resolution. In particular:
83 // - An undefined weak is still weak when it resolves to a shared library.96 // - An undefined weak is still weak when it resolves to a shared library.
...@@ -89,7 +102,7 @@ public:...@@ -89,7 +102,7 @@ public:
89 uint8_t Type; // symbol type102 uint8_t Type; // symbol type
90 uint8_t StOther; // st_other field value103 uint8_t StOther; // st_other field value
91104
92 const uint8_t SymbolKind;105 uint8_t SymbolKind;
93106
94 // Symbol visibility. This is the computed minimum visibility of all107 // Symbol visibility. This is the computed minimum visibility of all
95 // observed non-DSO symbols.108 // observed non-DSO symbols.
...@@ -128,8 +141,12 @@ public:...@@ -128,8 +141,12 @@ public:
128 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;141 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
129 }142 }
130143
131 // True if this is an undefined weak symbol.144 // True if this is an undefined weak symbol. This only works once
132 bool isUndefWeak() const { return isWeak() && isUndefined(); }145 // all input files have been added.
146 bool isUndefWeak() const {
147 // See comment on lazy symbols for details.
148 return isWeak() && (isUndefined() || isLazy());
149 }
133150
134 StringRef getName() const {151 StringRef getName() const {
135 if (NameSize == (uint32_t)-1)152 if (NameSize == (uint32_t)-1)
...@@ -137,10 +154,16 @@ public:...@@ -137,10 +154,16 @@ public:
137 return {NameData, NameSize};154 return {NameData, NameSize};
138 }155 }
139156
157 void setName(StringRef S) {
158 NameData = S.data();
159 NameSize = S.size();
160 }
161
140 void parseSymbolVersion();162 void parseSymbolVersion();
141163
142 bool isInGot() const { return GotIndex != -1U; }164 bool isInGot() const { return GotIndex != -1U; }
143 bool isInPlt() const { return PltIndex != -1U; }165 bool isInPlt() const { return PltIndex != -1U; }
166 bool isInPPC64Branchlt() const { return PPC64BranchltIndex != 0xffff; }
144167
145 uint64_t getVA(int64_t Addend = 0) const;168 uint64_t getVA(int64_t Addend = 0) const;
146169
...@@ -149,7 +172,8 @@ public:...@@ -149,7 +172,8 @@ public:
149 uint64_t getGotPltOffset() const;172 uint64_t getGotPltOffset() const;
150 uint64_t getGotPltVA() const;173 uint64_t getGotPltVA() const;
151 uint64_t getPltVA() const;174 uint64_t getPltVA() const;
152 uint64_t getPltOffset() const;175 uint64_t getPPC64LongBranchTableVA() const;
176 uint64_t getPPC64LongBranchOffset() const;
153 uint64_t getSize() const;177 uint64_t getSize() const;
154 OutputSection *getOutputSection() const;178 OutputSection *getOutputSection() const;
155179
...@@ -159,7 +183,8 @@ protected:...@@ -159,7 +183,8 @@ protected:
159 : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),183 : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
160 Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),184 Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
161 IsInIplt(false), IsInIgot(false), IsPreemptible(false),185 IsInIplt(false), IsInIgot(false), IsPreemptible(false),
162 Used(!Config->GcSections), NeedsTocRestore(false) {}186 Used(!Config->GcSections), NeedsTocRestore(false),
187 ScriptDefined(false) {}
163188
164public:189public:
165 // True the symbol should point to its PLT entry.190 // True the symbol should point to its PLT entry.
...@@ -182,12 +207,8 @@ public:...@@ -182,12 +207,8 @@ public:
182 // PPC64 toc pointer.207 // PPC64 toc pointer.
183 unsigned NeedsTocRestore : 1;208 unsigned NeedsTocRestore : 1;
184209
185 // The Type field may also have this value. It means that we have not yet seen210 // True if this symbol is defined by a linker script.
186 // a non-Lazy symbol with this name, so we don't know what its type is. The211 unsigned ScriptDefined : 1;
187 // Type field is normally set to this value for Lazy symbols unless we saw a
188 // weak undefined symbol first, in which case we need to remember the original
189 // symbol's type in order to check for TLS mismatches.
190 enum { UnknownType = 255 };
191212
192 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }213 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
193 bool isTls() const { return Type == llvm::ELF::STT_TLS; }214 bool isTls() const { return Type == llvm::ELF::STT_TLS; }
...@@ -286,6 +307,7 @@ public:...@@ -286,6 +307,7 @@ public:
286 static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }307 static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
287308
288 InputFile *fetch();309 InputFile *fetch();
310 MemoryBufferRef getMemberBuffer();
289311
290private:312private:
291 const llvm::object::Archive::Symbol Sym;313 const llvm::object::Archive::Symbol Sym;
...@@ -330,7 +352,8 @@ struct ElfSym {...@@ -330,7 +352,8 @@ struct ElfSym {
330 static Defined *MipsGpDisp;352 static Defined *MipsGpDisp;
331 static Defined *MipsLocalGp;353 static Defined *MipsLocalGp;
332354
333 // __rela_iplt_end or __rel_iplt_end355 // __rel{,a}_iplt_{start,end} symbols.
356 static Defined *RelaIpltStart;
334 static Defined *RelaIpltEnd;357 static Defined *RelaIpltEnd;
335};358};
336359
...@@ -349,6 +372,8 @@ void printTraceSymbol(Symbol *Sym);...@@ -349,6 +372,8 @@ void printTraceSymbol(Symbol *Sym);
349372
350template <typename T, typename... ArgT>373template <typename T, typename... ArgT>
351void replaceSymbol(Symbol *S, ArgT &&... Arg) {374void replaceSymbol(Symbol *S, ArgT &&... Arg) {
375 using llvm::ELF::STT_TLS;
376
352 static_assert(std::is_trivially_destructible<T>(),377 static_assert(std::is_trivially_destructible<T>(),
353 "Symbol types must be trivially destructible");378 "Symbol types must be trivially destructible");
354 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");379 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
...@@ -367,6 +392,19 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {...@@ -367,6 +392,19 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
367 S->ExportDynamic = Sym.ExportDynamic;392 S->ExportDynamic = Sym.ExportDynamic;
368 S->CanInline = Sym.CanInline;393 S->CanInline = Sym.CanInline;
369 S->Traced = Sym.Traced;394 S->Traced = Sym.Traced;
395 S->ScriptDefined = Sym.ScriptDefined;
396
397 // Symbols representing thread-local variables must be referenced by
398 // TLS-aware relocations, and non-TLS symbols must be reference by
399 // non-TLS relocations, so there's a clear distinction between TLS
400 // and non-TLS symbols. It is an error if the same symbol is defined
401 // as a TLS symbol in one file and as a non-TLS symbol in other file.
402 bool TlsMismatch = (Sym.Type == STT_TLS && S->Type != STT_TLS) ||
403 (Sym.Type != STT_TLS && S->Type == STT_TLS);
404
405 if (Sym.SymbolKind != Symbol::PlaceholderKind && TlsMismatch && !Sym.isLazy())
406 error("TLS attribute mismatch: " + toString(Sym) + "\n>>> defined in " +
407 toString(Sym.File) + "\n>>> defined in " + toString(S->File));
370408
371 // Print out a log message if --trace-symbol was specified.409 // Print out a log message if --trace-symbol was specified.
372 // This is for debugging.410 // This is for debugging.
...@@ -374,10 +412,8 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {...@@ -374,10 +412,8 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
374 printTraceSymbol(S);412 printTraceSymbol(S);
375}413}
376414
377void warnUnorderableSymbol(const Symbol *Sym);415void maybeWarnUnorderableSymbol(const Symbol *Sym);
378} // namespace elf416} // namespace elf
379
380std::string toString(const elf::Symbol &B);
381} // namespace lld417} // namespace lld
382418
383#endif419#endif
deps/lld/ELF/SyntheticSections.cpp+290-214
...@@ -30,10 +30,11 @@...@@ -30,10 +30,11 @@
30#include "lld/Common/Threads.h"30#include "lld/Common/Threads.h"
31#include "lld/Common/Version.h"31#include "lld/Common/Version.h"
32#include "llvm/ADT/SetOperations.h"32#include "llvm/ADT/SetOperations.h"
33#include "llvm/ADT/StringExtras.h"
33#include "llvm/BinaryFormat/Dwarf.h"34#include "llvm/BinaryFormat/Dwarf.h"
34#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"35#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
35#include "llvm/Object/Decompressor.h"
36#include "llvm/Object/ELFObjectFile.h"36#include "llvm/Object/ELFObjectFile.h"
37#include "llvm/Support/Compression.h"
37#include "llvm/Support/Endian.h"38#include "llvm/Support/Endian.h"
38#include "llvm/Support/LEB128.h"39#include "llvm/Support/LEB128.h"
39#include "llvm/Support/MD5.h"40#include "llvm/Support/MD5.h"
...@@ -104,7 +105,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {...@@ -104,7 +105,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
104 Create = true;105 Create = true;
105106
106 std::string Filename = toString(Sec->File);107 std::string Filename = toString(Sec->File);
107 const size_t Size = Sec->Data.size();108 const size_t Size = Sec->data().size();
108 // Older version of BFD (such as the default FreeBSD linker) concatenate109 // Older version of BFD (such as the default FreeBSD linker) concatenate
109 // .MIPS.abiflags instead of merging. To allow for this case (or potential110 // .MIPS.abiflags instead of merging. To allow for this case (or potential
110 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags111 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
...@@ -113,7 +114,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {...@@ -113,7 +114,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
113 Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));114 Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
114 return nullptr;115 return nullptr;
115 }116 }
116 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->Data.data());117 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
117 if (S->version != 0) {118 if (S->version != 0) {
118 error(Filename + ": unexpected .MIPS.abiflags version " +119 error(Filename + ": unexpected .MIPS.abiflags version " +
119 Twine(S->version));120 Twine(S->version));
...@@ -153,7 +154,7 @@ template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {...@@ -153,7 +154,7 @@ template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
153 Options->size = getSize();154 Options->size = getSize();
154155
155 if (!Config->Relocatable)156 if (!Config->Relocatable)
156 Reginfo.ri_gp_value = InX::MipsGot->getGp();157 Reginfo.ri_gp_value = In.MipsGot->getGp();
157 memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));158 memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
158}159}
159160
...@@ -176,7 +177,7 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {...@@ -176,7 +177,7 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
176 Sec->Live = false;177 Sec->Live = false;
177178
178 std::string Filename = toString(Sec->File);179 std::string Filename = toString(Sec->File);
179 ArrayRef<uint8_t> D = Sec->Data;180 ArrayRef<uint8_t> D = Sec->data();
180181
181 while (!D.empty()) {182 while (!D.empty()) {
182 if (D.size() < sizeof(Elf_Mips_Options)) {183 if (D.size() < sizeof(Elf_Mips_Options)) {
...@@ -210,7 +211,7 @@ MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)...@@ -210,7 +211,7 @@ MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
210211
211template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {212template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
212 if (!Config->Relocatable)213 if (!Config->Relocatable)
213 Reginfo.ri_gp_value = InX::MipsGot->getGp();214 Reginfo.ri_gp_value = In.MipsGot->getGp();
214 memcpy(Buf, &Reginfo, sizeof(Reginfo));215 memcpy(Buf, &Reginfo, sizeof(Reginfo));
215}216}
216217
...@@ -232,12 +233,12 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {...@@ -232,12 +233,12 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
232 for (InputSectionBase *Sec : Sections) {233 for (InputSectionBase *Sec : Sections) {
233 Sec->Live = false;234 Sec->Live = false;
234235
235 if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) {236 if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
236 error(toString(Sec->File) + ": invalid size of .reginfo section");237 error(toString(Sec->File) + ": invalid size of .reginfo section");
237 return nullptr;238 return nullptr;
238 }239 }
239240
240 auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());241 auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->data().data());
241 Reginfo.ri_gprmask |= R->ri_gprmask;242 Reginfo.ri_gprmask |= R->ri_gprmask;
242 Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;243 Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
243 };244 };
...@@ -260,8 +261,8 @@ Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,...@@ -260,8 +261,8 @@ Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
260 uint64_t Size, InputSectionBase &Section) {261 uint64_t Size, InputSectionBase &Section) {
261 auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,262 auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
262 Value, Size, &Section);263 Value, Size, &Section);
263 if (InX::SymTab)264 if (In.SymTab)
264 InX::SymTab->addSymbol(S);265 In.SymTab->addSymbol(S);
265 return S;266 return S;
266}267}
267268
...@@ -502,7 +503,7 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {...@@ -502,7 +503,7 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
502 uint8_t *Buf = getParent()->Loc + OutSecOff;503 uint8_t *Buf = getParent()->Loc + OutSecOff;
503 std::vector<FdeData> Ret;504 std::vector<FdeData> Ret;
504505
505 uint64_t VA = InX::EhFrameHdr->getVA();506 uint64_t VA = In.EhFrameHdr->getVA();
506 for (CieRecord *Rec : CieRecords) {507 for (CieRecord *Rec : CieRecords) {
507 uint8_t Enc = getFdeEncoding(Rec->Cie);508 uint8_t Enc = getFdeEncoding(Rec->Cie);
508 for (EhSectionPiece *Fde : Rec->Fdes) {509 for (EhSectionPiece *Fde : Rec->Fdes) {
...@@ -937,7 +938,7 @@ template <class ELFT> void MipsGotSection::build() {...@@ -937,7 +938,7 @@ template <class ELFT> void MipsGotSection::build() {
937 Symbol *S = P.first;938 Symbol *S = P.first;
938 uint64_t Offset = P.second * Config->Wordsize;939 uint64_t Offset = P.second * Config->Wordsize;
939 if (S->IsPreemptible)940 if (S->IsPreemptible)
940 InX::RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);941 In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
941 }942 }
942 for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {943 for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
943 Symbol *S = P.first;944 Symbol *S = P.first;
...@@ -945,7 +946,7 @@ template <class ELFT> void MipsGotSection::build() {...@@ -945,7 +946,7 @@ template <class ELFT> void MipsGotSection::build() {
945 if (S == nullptr) {946 if (S == nullptr) {
946 if (!Config->Pic)947 if (!Config->Pic)
947 continue;948 continue;
948 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);949 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
949 } else {950 } else {
950 // When building a shared library we still need a dynamic relocation951 // When building a shared library we still need a dynamic relocation
951 // for the module index. Therefore only checking for952 // for the module index. Therefore only checking for
...@@ -953,13 +954,13 @@ template <class ELFT> void MipsGotSection::build() {...@@ -953,13 +954,13 @@ template <class ELFT> void MipsGotSection::build() {
953 // thread-locals that have been marked as local through a linker script)954 // thread-locals that have been marked as local through a linker script)
954 if (!S->IsPreemptible && !Config->Pic)955 if (!S->IsPreemptible && !Config->Pic)
955 continue;956 continue;
956 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);957 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
957 // However, we can skip writing the TLS offset reloc for non-preemptible958 // However, we can skip writing the TLS offset reloc for non-preemptible
958 // symbols since it is known even in shared libraries959 // symbols since it is known even in shared libraries
959 if (!S->IsPreemptible)960 if (!S->IsPreemptible)
960 continue;961 continue;
961 Offset += Config->Wordsize;962 Offset += Config->Wordsize;
962 InX::RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);963 In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
963 }964 }
964 }965 }
965966
...@@ -971,7 +972,7 @@ template <class ELFT> void MipsGotSection::build() {...@@ -971,7 +972,7 @@ template <class ELFT> void MipsGotSection::build() {
971 // Dynamic relocations for "global" entries.972 // Dynamic relocations for "global" entries.
972 for (const std::pair<Symbol *, size_t> &P : Got.Global) {973 for (const std::pair<Symbol *, size_t> &P : Got.Global) {
973 uint64_t Offset = P.second * Config->Wordsize;974 uint64_t Offset = P.second * Config->Wordsize;
974 InX::RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);975 In.RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
975 }976 }
976 if (!Config->Pic)977 if (!Config->Pic)
977 continue;978 continue;
...@@ -981,14 +982,14 @@ template <class ELFT> void MipsGotSection::build() {...@@ -981,14 +982,14 @@ template <class ELFT> void MipsGotSection::build() {
981 size_t PageCount = L.second.Count;982 size_t PageCount = L.second.Count;
982 for (size_t PI = 0; PI < PageCount; ++PI) {983 for (size_t PI = 0; PI < PageCount; ++PI) {
983 uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;984 uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
984 InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,985 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
985 int64_t(PI * 0x10000)});986 int64_t(PI * 0x10000)});
986 }987 }
987 }988 }
988 for (const std::pair<GotEntry, size_t> &P : Got.Local16) {989 for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
989 uint64_t Offset = P.second * Config->Wordsize;990 uint64_t Offset = P.second * Config->Wordsize;
990 InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,991 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
991 P.first.first, P.first.second});992 P.first.first, P.first.second});
992 }993 }
993 }994 }
994}995}
...@@ -1200,21 +1201,21 @@ DynamicSection<ELFT>::DynamicSection()...@@ -1200,21 +1201,21 @@ DynamicSection<ELFT>::DynamicSection()
1200 // Add strings to .dynstr early so that .dynstr's size will be1201 // Add strings to .dynstr early so that .dynstr's size will be
1201 // fixed early.1202 // fixed early.
1202 for (StringRef S : Config->FilterList)1203 for (StringRef S : Config->FilterList)
1203 addInt(DT_FILTER, InX::DynStrTab->addString(S));1204 addInt(DT_FILTER, In.DynStrTab->addString(S));
1204 for (StringRef S : Config->AuxiliaryList)1205 for (StringRef S : Config->AuxiliaryList)
1205 addInt(DT_AUXILIARY, InX::DynStrTab->addString(S));1206 addInt(DT_AUXILIARY, In.DynStrTab->addString(S));
12061207
1207 if (!Config->Rpath.empty())1208 if (!Config->Rpath.empty())
1208 addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,1209 addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
1209 InX::DynStrTab->addString(Config->Rpath));1210 In.DynStrTab->addString(Config->Rpath));
12101211
1211 for (InputFile *File : SharedFiles) {1212 for (InputFile *File : SharedFiles) {
1212 SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);1213 SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
1213 if (F->IsNeeded)1214 if (F->IsNeeded)
1214 addInt(DT_NEEDED, InX::DynStrTab->addString(F->SoName));1215 addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
1215 }1216 }
1216 if (!Config->SoName.empty())1217 if (!Config->SoName.empty())
1217 addInt(DT_SONAME, InX::DynStrTab->addString(Config->SoName));1218 addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
1218}1219}
12191220
1220template <class ELFT>1221template <class ELFT>
...@@ -1254,18 +1255,33 @@ void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {...@@ -1254,18 +1255,33 @@ void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
1254 Entries.push_back({Tag, [=] { return Sym->getVA(); }});1255 Entries.push_back({Tag, [=] { return Sym->getVA(); }});
1255}1256}
12561257
1258// A Linker script may assign the RELA relocation sections to the same
1259// output section. When this occurs we cannot just use the OutputSection
1260// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
1261// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
1262static uint64_t addPltRelSz() {
1263 size_t Size = In.RelaPlt->getSize();
1264 if (In.RelaIplt->getParent() == In.RelaPlt->getParent() &&
1265 In.RelaIplt->Name == In.RelaPlt->Name)
1266 Size += In.RelaIplt->getSize();
1267 return Size;
1268}
1269
1257// Add remaining entries to complete .dynamic contents.1270// Add remaining entries to complete .dynamic contents.
1258template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {1271template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1259 if (this->Size)
1260 return; // Already finalized.
1261
1262 // Set DT_FLAGS and DT_FLAGS_1.1272 // Set DT_FLAGS and DT_FLAGS_1.
1263 uint32_t DtFlags = 0;1273 uint32_t DtFlags = 0;
1264 uint32_t DtFlags1 = 0;1274 uint32_t DtFlags1 = 0;
1265 if (Config->Bsymbolic)1275 if (Config->Bsymbolic)
1266 DtFlags |= DF_SYMBOLIC;1276 DtFlags |= DF_SYMBOLIC;
1277 if (Config->ZGlobal)
1278 DtFlags1 |= DF_1_GLOBAL;
1267 if (Config->ZInitfirst)1279 if (Config->ZInitfirst)
1268 DtFlags1 |= DF_1_INITFIRST;1280 DtFlags1 |= DF_1_INITFIRST;
1281 if (Config->ZInterpose)
1282 DtFlags1 |= DF_1_INTERPOSE;
1283 if (Config->ZNodefaultlib)
1284 DtFlags1 |= DF_1_NODEFLIB;
1269 if (Config->ZNodelete)1285 if (Config->ZNodelete)
1270 DtFlags1 |= DF_1_NODELETE;1286 DtFlags1 |= DF_1_NODELETE;
1271 if (Config->ZNodlopen)1287 if (Config->ZNodlopen)
...@@ -1297,10 +1313,12 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {...@@ -1297,10 +1313,12 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1297 if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)1313 if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
1298 addInt(DT_DEBUG, 0);1314 addInt(DT_DEBUG, 0);
12991315
1300 this->Link = InX::DynStrTab->getParent()->SectionIndex;1316 if (OutputSection *Sec = In.DynStrTab->getParent())
1301 if (!InX::RelaDyn->empty()) {1317 this->Link = Sec->SectionIndex;
1302 addInSec(InX::RelaDyn->DynamicTag, InX::RelaDyn);1318
1303 addSize(InX::RelaDyn->SizeDynamicTag, InX::RelaDyn->getParent());1319 if (!In.RelaDyn->empty()) {
1320 addInSec(In.RelaDyn->DynamicTag, In.RelaDyn);
1321 addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent());
13041322
1305 bool IsRela = Config->IsRela;1323 bool IsRela = Config->IsRela;
1306 addInt(IsRela ? DT_RELAENT : DT_RELENT,1324 addInt(IsRela ? DT_RELAENT : DT_RELENT,
...@@ -1310,16 +1328,16 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {...@@ -1310,16 +1328,16 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1310 // The problem is in the tight relation between dynamic1328 // The problem is in the tight relation between dynamic
1311 // relocations and GOT. So do not emit this tag on MIPS.1329 // relocations and GOT. So do not emit this tag on MIPS.
1312 if (Config->EMachine != EM_MIPS) {1330 if (Config->EMachine != EM_MIPS) {
1313 size_t NumRelativeRels = InX::RelaDyn->getRelativeRelocCount();1331 size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount();
1314 if (Config->ZCombreloc && NumRelativeRels)1332 if (Config->ZCombreloc && NumRelativeRels)
1315 addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);1333 addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
1316 }1334 }
1317 }1335 }
1318 if (InX::RelrDyn && !InX::RelrDyn->Relocs.empty()) {1336 if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) {
1319 addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,1337 addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
1320 InX::RelrDyn);1338 In.RelrDyn);
1321 addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,1339 addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
1322 InX::RelrDyn->getParent());1340 In.RelrDyn->getParent());
1323 addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,1341 addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
1324 sizeof(Elf_Relr));1342 sizeof(Elf_Relr));
1325 }1343 }
...@@ -1329,33 +1347,33 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {...@@ -1329,33 +1347,33 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1329 // as RelaIplt have. And we still want to emit proper dynamic tags for that1347 // as RelaIplt have. And we still want to emit proper dynamic tags for that
1330 // case, so here we always use RelaPlt as marker for the begining of1348 // case, so here we always use RelaPlt as marker for the begining of
1331 // .rel[a].plt section.1349 // .rel[a].plt section.
1332 if (InX::RelaPlt->getParent()->Live) {1350 if (In.RelaPlt->getParent()->Live) {
1333 addInSec(DT_JMPREL, InX::RelaPlt);1351 addInSec(DT_JMPREL, In.RelaPlt);
1334 addSize(DT_PLTRELSZ, InX::RelaPlt->getParent());1352 Entries.push_back({DT_PLTRELSZ, addPltRelSz});
1335 switch (Config->EMachine) {1353 switch (Config->EMachine) {
1336 case EM_MIPS:1354 case EM_MIPS:
1337 addInSec(DT_MIPS_PLTGOT, InX::GotPlt);1355 addInSec(DT_MIPS_PLTGOT, In.GotPlt);
1338 break;1356 break;
1339 case EM_SPARCV9:1357 case EM_SPARCV9:
1340 addInSec(DT_PLTGOT, InX::Plt);1358 addInSec(DT_PLTGOT, In.Plt);
1341 break;1359 break;
1342 default:1360 default:
1343 addInSec(DT_PLTGOT, InX::GotPlt);1361 addInSec(DT_PLTGOT, In.GotPlt);
1344 break;1362 break;
1345 }1363 }
1346 addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);1364 addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
1347 }1365 }
13481366
1349 addInSec(DT_SYMTAB, InX::DynSymTab);1367 addInSec(DT_SYMTAB, In.DynSymTab);
1350 addInt(DT_SYMENT, sizeof(Elf_Sym));1368 addInt(DT_SYMENT, sizeof(Elf_Sym));
1351 addInSec(DT_STRTAB, InX::DynStrTab);1369 addInSec(DT_STRTAB, In.DynStrTab);
1352 addInt(DT_STRSZ, InX::DynStrTab->getSize());1370 addInt(DT_STRSZ, In.DynStrTab->getSize());
1353 if (!Config->ZText)1371 if (!Config->ZText)
1354 addInt(DT_TEXTREL, 0);1372 addInt(DT_TEXTREL, 0);
1355 if (InX::GnuHashTab)1373 if (In.GnuHashTab)
1356 addInSec(DT_GNU_HASH, InX::GnuHashTab);1374 addInSec(DT_GNU_HASH, In.GnuHashTab);
1357 if (InX::HashTab)1375 if (In.HashTab)
1358 addInSec(DT_HASH, InX::HashTab);1376 addInSec(DT_HASH, In.HashTab);
13591377
1360 if (Out::PreinitArray) {1378 if (Out::PreinitArray) {
1361 addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);1379 addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
...@@ -1377,47 +1395,47 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {...@@ -1377,47 +1395,47 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1377 if (B->isDefined())1395 if (B->isDefined())
1378 addSym(DT_FINI, B);1396 addSym(DT_FINI, B);
13791397
1380 bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;1398 bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0;
1381 if (HasVerNeed || In<ELFT>::VerDef)1399 if (HasVerNeed || In.VerDef)
1382 addInSec(DT_VERSYM, In<ELFT>::VerSym);1400 addInSec(DT_VERSYM, InX<ELFT>::VerSym);
1383 if (In<ELFT>::VerDef) {1401 if (In.VerDef) {
1384 addInSec(DT_VERDEF, In<ELFT>::VerDef);1402 addInSec(DT_VERDEF, In.VerDef);
1385 addInt(DT_VERDEFNUM, getVerDefNum());1403 addInt(DT_VERDEFNUM, getVerDefNum());
1386 }1404 }
1387 if (HasVerNeed) {1405 if (HasVerNeed) {
1388 addInSec(DT_VERNEED, In<ELFT>::VerNeed);1406 addInSec(DT_VERNEED, InX<ELFT>::VerNeed);
1389 addInt(DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum());1407 addInt(DT_VERNEEDNUM, InX<ELFT>::VerNeed->getNeedNum());
1390 }1408 }
13911409
1392 if (Config->EMachine == EM_MIPS) {1410 if (Config->EMachine == EM_MIPS) {
1393 addInt(DT_MIPS_RLD_VERSION, 1);1411 addInt(DT_MIPS_RLD_VERSION, 1);
1394 addInt(DT_MIPS_FLAGS, RHF_NOTPOT);1412 addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
1395 addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());1413 addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
1396 addInt(DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols());1414 addInt(DT_MIPS_SYMTABNO, In.DynSymTab->getNumSymbols());
13971415
1398 add(DT_MIPS_LOCAL_GOTNO, [] { return InX::MipsGot->getLocalEntriesNum(); });1416 add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });
13991417
1400 if (const Symbol *B = InX::MipsGot->getFirstGlobalEntry())1418 if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
1401 addInt(DT_MIPS_GOTSYM, B->DynsymIndex);1419 addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
1402 else1420 else
1403 addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols());1421 addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols());
1404 addInSec(DT_PLTGOT, InX::MipsGot);1422 addInSec(DT_PLTGOT, In.MipsGot);
1405 if (InX::MipsRldMap) {1423 if (In.MipsRldMap) {
1406 if (!Config->Pie)1424 if (!Config->Pie)
1407 addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);1425 addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
1408 // Store the offset to the .rld_map section1426 // Store the offset to the .rld_map section
1409 // relative to the address of the tag.1427 // relative to the address of the tag.
1410 addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap);1428 addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap);
1411 }1429 }
1412 }1430 }
14131431
1414 // Glink dynamic tag is required by the V2 abi if the plt section isn't empty.1432 // Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
1415 if (Config->EMachine == EM_PPC64 && !InX::Plt->empty()) {1433 if (Config->EMachine == EM_PPC64 && !In.Plt->empty()) {
1416 // The Glink tag points to 32 bytes before the first lazy symbol resolution1434 // The Glink tag points to 32 bytes before the first lazy symbol resolution
1417 // stub, which starts directly after the header.1435 // stub, which starts directly after the header.
1418 Entries.push_back({DT_PPC64_GLINK, [=] {1436 Entries.push_back({DT_PPC64_GLINK, [=] {
1419 unsigned Offset = Target->PltHeaderSize - 32;1437 unsigned Offset = Target->PltHeaderSize - 32;
1420 return InX::Plt->getVA(0) + Offset;1438 return In.Plt->getVA(0) + Offset;
1421 }});1439 }});
1422 }1440 }
14231441
...@@ -1486,13 +1504,19 @@ void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {...@@ -1486,13 +1504,19 @@ void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
1486}1504}
14871505
1488void RelocationBaseSection::finalizeContents() {1506void RelocationBaseSection::finalizeContents() {
1489 // If all relocations are R_*_RELATIVE they don't refer to any1507 // When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
1490 // dynamic symbol and we don't need a dynamic symbol table. If that1508 // relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
1491 // is the case, just use 0 as the link.1509 // case.
1492 Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0;1510 InputSection *SymTab = Config->Relocatable ? In.SymTab : In.DynSymTab;
1511 if (SymTab && SymTab->getParent())
1512 getParent()->Link = SymTab->getParent()->SectionIndex;
1513 else
1514 getParent()->Link = 0;
14931515
1494 // Set required output section properties.1516 if (In.RelaPlt == this)
1495 getParent()->Link = Link;1517 getParent()->Info = In.GotPlt->getParent()->SectionIndex;
1518 if (In.RelaIplt == this)
1519 getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
1496}1520}
14971521
1498RelrBaseSection::RelrBaseSection()1522RelrBaseSection::RelrBaseSection()
...@@ -1621,10 +1645,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {...@@ -1621,10 +1645,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
1621 NonRelatives.push_back(R);1645 NonRelatives.push_back(R);
1622 }1646 }
16231647
1624 llvm::sort(Relatives.begin(), Relatives.end(),1648 llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
1625 [](const Elf_Rel &A, const Elf_Rel &B) {1649 return A.r_offset < B.r_offset;
1626 return A.r_offset < B.r_offset;1650 });
1627 });
16281651
1629 // Try to find groups of relative relocations which are spaced one word1652 // Try to find groups of relative relocations which are spaced one word
1630 // apart from one another. These generally correspond to vtable entries. The1653 // apart from one another. These generally correspond to vtable entries. The
...@@ -1702,10 +1725,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {...@@ -1702,10 +1725,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
1702 }1725 }
17031726
1704 // Finally the non-relative relocations.1727 // Finally the non-relative relocations.
1705 llvm::sort(NonRelatives.begin(), NonRelatives.end(),1728 llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
1706 [](const Elf_Rela &A, const Elf_Rela &B) {1729 return A.r_offset < B.r_offset;
1707 return A.r_offset < B.r_offset;1730 });
1708 });
1709 if (!NonRelatives.empty()) {1731 if (!NonRelatives.empty()) {
1710 Add(NonRelatives.size());1732 Add(NonRelatives.size());
1711 Add(HasAddendIfRela);1733 Add(HasAddendIfRela);
...@@ -1720,6 +1742,11 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {...@@ -1720,6 +1742,11 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
1720 }1742 }
1721 }1743 }
17221744
1745 // Don't allow the section to shrink; otherwise the size of the section can
1746 // oscillate infinitely.
1747 if (RelocData.size() < OldSize)
1748 RelocData.append(OldSize - RelocData.size(), 0);
1749
1723 // Returns whether the section size changed. We need to keep recomputing both1750 // Returns whether the section size changed. We need to keep recomputing both
1724 // section layout and the contents of this section until the size converges1751 // section layout and the contents of this section until the size converges
1725 // because changing this section's size can affect section layout, which in1752 // because changing this section's size can affect section layout, which in
...@@ -1843,10 +1870,13 @@ static bool sortMipsSymbols(const SymbolTableEntry &L,...@@ -1843,10 +1870,13 @@ static bool sortMipsSymbols(const SymbolTableEntry &L,
1843}1870}
18441871
1845void SymbolTableBaseSection::finalizeContents() {1872void SymbolTableBaseSection::finalizeContents() {
1846 getParent()->Link = StrTabSec.getParent()->SectionIndex;1873 if (OutputSection *Sec = StrTabSec.getParent())
1874 getParent()->Link = Sec->SectionIndex;
18471875
1848 if (this->Type != SHT_DYNSYM)1876 if (this->Type != SHT_DYNSYM) {
1877 sortSymTabSymbols();
1849 return;1878 return;
1879 }
18501880
1851 // If it is a .dynsym, there should be no local symbols, but we need1881 // If it is a .dynsym, there should be no local symbols, but we need
1852 // to do a few things for the dynamic linker.1882 // to do a few things for the dynamic linker.
...@@ -1855,9 +1885,9 @@ void SymbolTableBaseSection::finalizeContents() {...@@ -1855,9 +1885,9 @@ void SymbolTableBaseSection::finalizeContents() {
1855 // Because the first symbol entry is a null entry, 1 is the first.1885 // Because the first symbol entry is a null entry, 1 is the first.
1856 getParent()->Info = 1;1886 getParent()->Info = 1;
18571887
1858 if (InX::GnuHashTab) {1888 if (In.GnuHashTab) {
1859 // NB: It also sorts Symbols to meet the GNU hash table requirements.1889 // NB: It also sorts Symbols to meet the GNU hash table requirements.
1860 InX::GnuHashTab->addSymbols(Symbols);1890 In.GnuHashTab->addSymbols(Symbols);
1861 } else if (Config->EMachine == EM_MIPS) {1891 } else if (Config->EMachine == EM_MIPS) {
1862 std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);1892 std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
1863 }1893 }
...@@ -1874,9 +1904,7 @@ void SymbolTableBaseSection::finalizeContents() {...@@ -1874,9 +1904,7 @@ void SymbolTableBaseSection::finalizeContents() {
1874// Aside from above, we put local symbols in groups starting with the STT_FILE1904// Aside from above, we put local symbols in groups starting with the STT_FILE
1875// symbol. That is convenient for purpose of identifying where are local symbols1905// symbol. That is convenient for purpose of identifying where are local symbols
1876// coming from.1906// coming from.
1877void SymbolTableBaseSection::postThunkContents() {1907void SymbolTableBaseSection::sortSymTabSymbols() {
1878 assert(this->Type == SHT_SYMTAB);
1879
1880 // Move all local symbols before global symbols.1908 // Move all local symbols before global symbols.
1881 auto E = std::stable_partition(1909 auto E = std::stable_partition(
1882 Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {1910 Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
...@@ -1948,7 +1976,8 @@ static uint32_t getSymSectionIndex(Symbol *Sym) {...@@ -1948,7 +1976,8 @@ static uint32_t getSymSectionIndex(Symbol *Sym) {
1948 if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)1976 if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
1949 return SHN_UNDEF;1977 return SHN_UNDEF;
1950 if (const OutputSection *OS = Sym->getOutputSection())1978 if (const OutputSection *OS = Sym->getOutputSection())
1951 return OS->SectionIndex >= SHN_LORESERVE ? SHN_XINDEX : OS->SectionIndex;1979 return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
1980 : OS->SectionIndex;
1952 return SHN_ABS;1981 return SHN_ABS;
1953}1982}
19541983
...@@ -2038,7 +2067,7 @@ void SymtabShndxSection::writeTo(uint8_t *Buf) {...@@ -2038,7 +2067,7 @@ void SymtabShndxSection::writeTo(uint8_t *Buf) {
2038 // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,2067 // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
2039 // we need to write actual index, otherwise, we must write SHN_UNDEF(0).2068 // we need to write actual index, otherwise, we must write SHN_UNDEF(0).
2040 Buf += 4; // Ignore .symtab[0] entry.2069 Buf += 4; // Ignore .symtab[0] entry.
2041 for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) {2070 for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
2042 if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)2071 if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
2043 write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);2072 write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
2044 Buf += 4;2073 Buf += 4;
...@@ -2059,11 +2088,11 @@ bool SymtabShndxSection::empty() const {...@@ -2059,11 +2088,11 @@ bool SymtabShndxSection::empty() const {
2059}2088}
20602089
2061void SymtabShndxSection::finalizeContents() {2090void SymtabShndxSection::finalizeContents() {
2062 getParent()->Link = InX::SymTab->getParent()->SectionIndex;2091 getParent()->Link = In.SymTab->getParent()->SectionIndex;
2063}2092}
20642093
2065size_t SymtabShndxSection::getSize() const {2094size_t SymtabShndxSection::getSize() const {
2066 return InX::SymTab->getNumSymbols() * 4;2095 return In.SymTab->getNumSymbols() * 4;
2067}2096}
20682097
2069// .hash and .gnu.hash sections contain on-disk hash tables that map2098// .hash and .gnu.hash sections contain on-disk hash tables that map
...@@ -2102,7 +2131,8 @@ GnuHashTableSection::GnuHashTableSection()...@@ -2102,7 +2131,8 @@ GnuHashTableSection::GnuHashTableSection()
2102}2131}
21032132
2104void GnuHashTableSection::finalizeContents() {2133void GnuHashTableSection::finalizeContents() {
2105 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;2134 if (OutputSection *Sec = In.DynSymTab->getParent())
2135 getParent()->Link = Sec->SectionIndex;
21062136
2107 // Computes bloom filter size in word size. We want to allocate 122137 // Computes bloom filter size in word size. We want to allocate 12
2108 // bits for each symbol. It must be a power of two.2138 // bits for each symbol. It must be a power of two.
...@@ -2127,7 +2157,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {...@@ -2127,7 +2157,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
21272157
2128 // Write a header.2158 // Write a header.
2129 write32(Buf, NBuckets);2159 write32(Buf, NBuckets);
2130 write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size());2160 write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size());
2131 write32(Buf + 8, MaskWords);2161 write32(Buf + 8, MaskWords);
2132 write32(Buf + 12, Shift2);2162 write32(Buf + 12, Shift2);
2133 Buf += 16;2163 Buf += 16;
...@@ -2148,6 +2178,8 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {...@@ -2148,6 +2178,8 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
2148void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {2178void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
2149 unsigned C = Config->Is64 ? 64 : 32;2179 unsigned C = Config->Is64 ? 64 : 32;
2150 for (const Entry &Sym : Symbols) {2180 for (const Entry &Sym : Symbols) {
2181 // When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
2182 // the word using bits [0:5] and [26:31].
2151 size_t I = (Sym.Hash / C) & (MaskWords - 1);2183 size_t I = (Sym.Hash / C) & (MaskWords - 1);
2152 uint64_t Val = readUint(Buf + I * Config->Wordsize);2184 uint64_t Val = readUint(Buf + I * Config->Wordsize);
2153 Val |= uint64_t(1) << (Sym.Hash % C);2185 Val |= uint64_t(1) << (Sym.Hash % C);
...@@ -2232,13 +2264,14 @@ HashTableSection::HashTableSection()...@@ -2232,13 +2264,14 @@ HashTableSection::HashTableSection()
2232}2264}
22332265
2234void HashTableSection::finalizeContents() {2266void HashTableSection::finalizeContents() {
2235 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;2267 if (OutputSection *Sec = In.DynSymTab->getParent())
2268 getParent()->Link = Sec->SectionIndex;
22362269
2237 unsigned NumEntries = 2; // nbucket and nchain.2270 unsigned NumEntries = 2; // nbucket and nchain.
2238 NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.2271 NumEntries += In.DynSymTab->getNumSymbols(); // The chain entries.
22392272
2240 // Create as many buckets as there are symbols.2273 // Create as many buckets as there are symbols.
2241 NumEntries += InX::DynSymTab->getNumSymbols();2274 NumEntries += In.DynSymTab->getNumSymbols();
2242 this->Size = NumEntries * 4;2275 this->Size = NumEntries * 4;
2243}2276}
22442277
...@@ -2246,7 +2279,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {...@@ -2246,7 +2279,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {
2246 // See comment in GnuHashTableSection::writeTo.2279 // See comment in GnuHashTableSection::writeTo.
2247 memset(Buf, 0, Size);2280 memset(Buf, 0, Size);
22482281
2249 unsigned NumSymbols = InX::DynSymTab->getNumSymbols();2282 unsigned NumSymbols = In.DynSymTab->getNumSymbols();
22502283
2251 uint32_t *P = reinterpret_cast<uint32_t *>(Buf);2284 uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
2252 write32(P++, NumSymbols); // nbucket2285 write32(P++, NumSymbols); // nbucket
...@@ -2255,7 +2288,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {...@@ -2255,7 +2288,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {
2255 uint32_t *Buckets = P;2288 uint32_t *Buckets = P;
2256 uint32_t *Chains = P + NumSymbols;2289 uint32_t *Chains = P + NumSymbols;
22572290
2258 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {2291 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
2259 Symbol *Sym = S.Sym;2292 Symbol *Sym = S.Sym;
2260 StringRef Name = Sym->getName();2293 StringRef Name = Sym->getName();
2261 unsigned I = Sym->DynsymIndex;2294 unsigned I = Sym->DynsymIndex;
...@@ -2270,7 +2303,8 @@ void HashTableSection::writeTo(uint8_t *Buf) {...@@ -2270,7 +2303,8 @@ void HashTableSection::writeTo(uint8_t *Buf) {
2270PltSection::PltSection(bool IsIplt)2303PltSection::PltSection(bool IsIplt)
2271 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,2304 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
2272 Config->EMachine == EM_PPC64 ? ".glink" : ".plt"),2305 Config->EMachine == EM_PPC64 ? ".glink" : ".plt"),
2273 HeaderSize(IsIplt ? 0 : Target->PltHeaderSize), IsIplt(IsIplt) {2306 HeaderSize(!IsIplt || Config->ZRetpolineplt ? Target->PltHeaderSize : 0),
2307 IsIplt(IsIplt) {
2274 // The PLT needs to be writable on SPARC as the dynamic linker will2308 // The PLT needs to be writable on SPARC as the dynamic linker will
2275 // modify the instructions in the PLT entries.2309 // modify the instructions in the PLT entries.
2276 if (Config->EMachine == EM_SPARCV9)2310 if (Config->EMachine == EM_SPARCV9)
...@@ -2278,9 +2312,9 @@ PltSection::PltSection(bool IsIplt)...@@ -2278,9 +2312,9 @@ PltSection::PltSection(bool IsIplt)
2278}2312}
22792313
2280void PltSection::writeTo(uint8_t *Buf) {2314void PltSection::writeTo(uint8_t *Buf) {
2281 // At beginning of PLT but not the IPLT, we have code to call the dynamic2315 // At beginning of PLT or retpoline IPLT, we have code to call the dynamic
2282 // linker to resolve dynsyms at runtime. Write such code.2316 // linker to resolve dynsyms at runtime. Write such code.
2283 if (!IsIplt)2317 if (HeaderSize > 0)
2284 Target->writePltHeader(Buf);2318 Target->writePltHeader(Buf);
2285 size_t Off = HeaderSize;2319 size_t Off = HeaderSize;
2286 // The IPlt is immediately after the Plt, account for this in RelOff2320 // The IPlt is immediately after the Plt, account for this in RelOff
...@@ -2298,9 +2332,9 @@ void PltSection::writeTo(uint8_t *Buf) {...@@ -2298,9 +2332,9 @@ void PltSection::writeTo(uint8_t *Buf) {
22982332
2299template <class ELFT> void PltSection::addEntry(Symbol &Sym) {2333template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
2300 Sym.PltIndex = Entries.size();2334 Sym.PltIndex = Entries.size();
2301 RelocationBaseSection *PltRelocSection = InX::RelaPlt;2335 RelocationBaseSection *PltRelocSection = In.RelaPlt;
2302 if (IsIplt) {2336 if (IsIplt) {
2303 PltRelocSection = InX::RelaIplt;2337 PltRelocSection = In.RelaIplt;
2304 Sym.IsInIplt = true;2338 Sym.IsInIplt = true;
2305 }2339 }
2306 unsigned RelOff =2340 unsigned RelOff =
...@@ -2326,14 +2360,14 @@ void PltSection::addSymbols() {...@@ -2326,14 +2360,14 @@ void PltSection::addSymbols() {
2326}2360}
23272361
2328unsigned PltSection::getPltRelocOff() const {2362unsigned PltSection::getPltRelocOff() const {
2329 return IsIplt ? InX::Plt->getSize() : 0;2363 return IsIplt ? In.Plt->getSize() : 0;
2330}2364}
23312365
2332// The string hash function for .gdb_index.2366// The string hash function for .gdb_index.
2333static uint32_t computeGdbHash(StringRef S) {2367static uint32_t computeGdbHash(StringRef S) {
2334 uint32_t H = 0;2368 uint32_t H = 0;
2335 for (uint8_t C : S)2369 for (uint8_t C : S)
2336 H = H * 67 + tolower(C) - 113;2370 H = H * 67 + toLower(C) - 113;
2337 return H;2371 return H;
2338}2372}
23392373
...@@ -2371,7 +2405,7 @@ static std::vector<InputSection *> getDebugInfoSections() {...@@ -2371,7 +2405,7 @@ static std::vector<InputSection *> getDebugInfoSections() {
23712405
2372static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {2406static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
2373 std::vector<GdbIndexSection::CuEntry> Ret;2407 std::vector<GdbIndexSection::CuEntry> Ret;
2374 for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units())2408 for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units())
2375 Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});2409 Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
2376 return Ret;2410 return Ret;
2377}2411}
...@@ -2381,12 +2415,15 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {...@@ -2381,12 +2415,15 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
2381 std::vector<GdbIndexSection::AddressEntry> Ret;2415 std::vector<GdbIndexSection::AddressEntry> Ret;
23822416
2383 uint32_t CuIdx = 0;2417 uint32_t CuIdx = 0;
2384 for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) {2418 for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
2385 DWARFAddressRangesVector Ranges;2419 Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
2386 Cu->collectAddressRanges(Ranges);2420 if (!Ranges) {
2421 error(toString(Sec) + ": " + toString(Ranges.takeError()));
2422 return {};
2423 }
23872424
2388 ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();2425 ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
2389 for (DWARFAddressRange &R : Ranges) {2426 for (DWARFAddressRange &R : *Ranges) {
2390 InputSectionBase *S = Sections[R.SectionIndex];2427 InputSectionBase *S = Sections[R.SectionIndex];
2391 if (!S || S == &InputSection::Discarded || !S->Live)2428 if (!S || S == &InputSection::Discarded || !S->Live)
2392 continue;2429 continue;
...@@ -2399,21 +2436,35 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {...@@ -2399,21 +2436,35 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
2399 }2436 }
2400 ++CuIdx;2437 ++CuIdx;
2401 }2438 }
2439
2402 return Ret;2440 return Ret;
2403}2441}
24042442
2405static std::vector<GdbIndexSection::NameTypeEntry>2443template <class ELFT>
2406readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) {2444static std::vector<GdbIndexSection::NameAttrEntry>
2407 StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection();2445readPubNamesAndTypes(const LLDDwarfObj<ELFT> &Obj,
2408 StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection();2446 const std::vector<GdbIndexSection::CuEntry> &CUs) {
24092447 const DWARFSection &PubNames = Obj.getGnuPubNamesSection();
2410 std::vector<GdbIndexSection::NameTypeEntry> Ret;2448 const DWARFSection &PubTypes = Obj.getGnuPubTypesSection();
2411 for (StringRef Sec : {Sec1, Sec2}) {2449
2412 DWARFDebugPubTable Table(Sec, Config->IsLE, true);2450 std::vector<GdbIndexSection::NameAttrEntry> Ret;
2413 for (const DWARFDebugPubTable::Set &Set : Table.getData())2451 for (const DWARFSection *Pub : {&PubNames, &PubTypes}) {
2452 DWARFDebugPubTable Table(Obj, *Pub, Config->IsLE, true);
2453 for (const DWARFDebugPubTable::Set &Set : Table.getData()) {
2454 // The value written into the constant pool is Kind << 24 | CuIndex. As we
2455 // don't know how many compilation units precede this object to compute
2456 // CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
2457 // the number of preceding compilation units later.
2458 uint32_t I =
2459 lower_bound(CUs, Set.Offset,
2460 [](GdbIndexSection::CuEntry CU, uint32_t Offset) {
2461 return CU.CuOffset < Offset;
2462 }) -
2463 CUs.begin();
2414 for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)2464 for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
2415 Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},2465 Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
2416 (Ent.Descriptor.toBits() << 24) | Idx});2466 (Ent.Descriptor.toBits() << 24) | I});
2467 }
2417 }2468 }
2418 return Ret;2469 return Ret;
2419}2470}
...@@ -2421,9 +2472,18 @@ readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) {...@@ -2421,9 +2472,18 @@ readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) {
2421// Create a list of symbols from a given list of symbol names and types2472// Create a list of symbols from a given list of symbol names and types
2422// by uniquifying them by name.2473// by uniquifying them by name.
2423static std::vector<GdbIndexSection::GdbSymbol>2474static std::vector<GdbIndexSection::GdbSymbol>
2424createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) {2475createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> NameAttrs,
2476 const std::vector<GdbIndexSection::GdbChunk> &Chunks) {
2425 typedef GdbIndexSection::GdbSymbol GdbSymbol;2477 typedef GdbIndexSection::GdbSymbol GdbSymbol;
2426 typedef GdbIndexSection::NameTypeEntry NameTypeEntry;2478 typedef GdbIndexSection::NameAttrEntry NameAttrEntry;
2479
2480 // For each chunk, compute the number of compilation units preceding it.
2481 uint32_t CuIdx = 0;
2482 std::vector<uint32_t> CuIdxs(Chunks.size());
2483 for (uint32_t I = 0, E = Chunks.size(); I != E; ++I) {
2484 CuIdxs[I] = CuIdx;
2485 CuIdx += Chunks[I].CompilationUnits.size();
2486 }
24272487
2428 // The number of symbols we will handle in this function is of the order2488 // The number of symbols we will handle in this function is of the order
2429 // of millions for very large executables, so we use multi-threading to2489 // of millions for very large executables, so we use multi-threading to
...@@ -2441,21 +2501,24 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) {...@@ -2441,21 +2501,24 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) {
2441 // Instantiate GdbSymbols while uniqufying them by name.2501 // Instantiate GdbSymbols while uniqufying them by name.
2442 std::vector<std::vector<GdbSymbol>> Symbols(NumShards);2502 std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
2443 parallelForEachN(0, Concurrency, [&](size_t ThreadId) {2503 parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
2444 for (ArrayRef<NameTypeEntry> Entries : NameTypes) {2504 uint32_t I = 0;
2445 for (const NameTypeEntry &Ent : Entries) {2505 for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
2506 for (const NameAttrEntry &Ent : Entries) {
2446 size_t ShardId = Ent.Name.hash() >> Shift;2507 size_t ShardId = Ent.Name.hash() >> Shift;
2447 if ((ShardId & (Concurrency - 1)) != ThreadId)2508 if ((ShardId & (Concurrency - 1)) != ThreadId)
2448 continue;2509 continue;
24492510
2511 uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
2450 size_t &Idx = Map[ShardId][Ent.Name];2512 size_t &Idx = Map[ShardId][Ent.Name];
2451 if (Idx) {2513 if (Idx) {
2452 Symbols[ShardId][Idx - 1].CuVector.push_back(Ent.Type);2514 Symbols[ShardId][Idx - 1].CuVector.push_back(V);
2453 continue;2515 continue;
2454 }2516 }
24552517
2456 Idx = Symbols[ShardId].size() + 1;2518 Idx = Symbols[ShardId].size() + 1;
2457 Symbols[ShardId].push_back({Ent.Name, {Ent.Type}, 0, 0});2519 Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0});
2458 }2520 }
2521 ++I;
2459 }2522 }
2460 });2523 });
24612524
...@@ -2498,7 +2561,7 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {...@@ -2498,7 +2561,7 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
2498 S->Live = false;2561 S->Live = false;
24992562
2500 std::vector<GdbChunk> Chunks(Sections.size());2563 std::vector<GdbChunk> Chunks(Sections.size());
2501 std::vector<std::vector<NameTypeEntry>> NameTypes(Sections.size());2564 std::vector<std::vector<NameAttrEntry>> NameAttrs(Sections.size());
25022565
2503 parallelForEachN(0, Sections.size(), [&](size_t I) {2566 parallelForEachN(0, Sections.size(), [&](size_t I) {
2504 ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();2567 ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
...@@ -2507,12 +2570,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {...@@ -2507,12 +2570,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
2507 Chunks[I].Sec = Sections[I];2570 Chunks[I].Sec = Sections[I];
2508 Chunks[I].CompilationUnits = readCuList(Dwarf);2571 Chunks[I].CompilationUnits = readCuList(Dwarf);
2509 Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);2572 Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);
2510 NameTypes[I] = readPubNamesAndTypes(Dwarf, I);2573 NameAttrs[I] = readPubNamesAndTypes<ELFT>(
2574 static_cast<const LLDDwarfObj<ELFT> &>(Dwarf.getDWARFObj()),
2575 Chunks[I].CompilationUnits);
2511 });2576 });
25122577
2513 auto *Ret = make<GdbIndexSection>();2578 auto *Ret = make<GdbIndexSection>();
2514 Ret->Chunks = std::move(Chunks);2579 Ret->Chunks = std::move(Chunks);
2515 Ret->Symbols = createSymbols(NameTypes);2580 Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
2516 Ret->initOutputSize();2581 Ret->initOutputSize();
2517 return Ret;2582 return Ret;
2518}2583}
...@@ -2570,8 +2635,9 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {...@@ -2570,8 +2635,9 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
25702635
2571 // Write the string pool.2636 // Write the string pool.
2572 Hdr->ConstantPoolOff = Buf - Start;2637 Hdr->ConstantPoolOff = Buf - Start;
2573 for (GdbSymbol &Sym : Symbols)2638 parallelForEach(Symbols, [&](GdbSymbol &Sym) {
2574 memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());2639 memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
2640 });
25752641
2576 // Write the CU vectors.2642 // Write the CU vectors.
2577 for (GdbSymbol &Sym : Symbols) {2643 for (GdbSymbol &Sym : Symbols) {
...@@ -2584,7 +2650,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {...@@ -2584,7 +2650,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
2584 }2650 }
2585}2651}
25862652
2587bool GdbIndexSection::empty() const { return !Out::DebugInfo; }2653bool GdbIndexSection::empty() const { return Chunks.empty(); }
25882654
2589EhFrameHeader::EhFrameHeader()2655EhFrameHeader::EhFrameHeader()
2590 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}2656 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
...@@ -2596,13 +2662,13 @@ EhFrameHeader::EhFrameHeader()...@@ -2596,13 +2662,13 @@ EhFrameHeader::EhFrameHeader()
2596void EhFrameHeader::writeTo(uint8_t *Buf) {2662void EhFrameHeader::writeTo(uint8_t *Buf) {
2597 typedef EhFrameSection::FdeData FdeData;2663 typedef EhFrameSection::FdeData FdeData;
25982664
2599 std::vector<FdeData> Fdes = InX::EhFrame->getFdeData();2665 std::vector<FdeData> Fdes = In.EhFrame->getFdeData();
26002666
2601 Buf[0] = 1;2667 Buf[0] = 1;
2602 Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;2668 Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
2603 Buf[2] = DW_EH_PE_udata4;2669 Buf[2] = DW_EH_PE_udata4;
2604 Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;2670 Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
2605 write32(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4);2671 write32(Buf + 4, In.EhFrame->getParent()->Addr - this->getVA() - 4);
2606 write32(Buf + 8, Fdes.size());2672 write32(Buf + 8, Fdes.size());
2607 Buf += 12;2673 Buf += 12;
26082674
...@@ -2615,13 +2681,12 @@ void EhFrameHeader::writeTo(uint8_t *Buf) {...@@ -2615,13 +2681,12 @@ void EhFrameHeader::writeTo(uint8_t *Buf) {
26152681
2616size_t EhFrameHeader::getSize() const {2682size_t EhFrameHeader::getSize() const {
2617 // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.2683 // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
2618 return 12 + InX::EhFrame->NumFdes * 8;2684 return 12 + In.EhFrame->NumFdes * 8;
2619}2685}
26202686
2621bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); }2687bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }
26222688
2623template <class ELFT>2689VersionDefinitionSection::VersionDefinitionSection()
2624VersionDefinitionSection<ELFT>::VersionDefinitionSection()
2625 : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),2690 : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
2626 ".gnu.version_d") {}2691 ".gnu.version_d") {}
26272692
...@@ -2631,12 +2696,13 @@ static StringRef getFileDefName() {...@@ -2631,12 +2696,13 @@ static StringRef getFileDefName() {
2631 return Config->OutputFile;2696 return Config->OutputFile;
2632}2697}
26332698
2634template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {2699void VersionDefinitionSection::finalizeContents() {
2635 FileDefNameOff = InX::DynStrTab->addString(getFileDefName());2700 FileDefNameOff = In.DynStrTab->addString(getFileDefName());
2636 for (VersionDefinition &V : Config->VersionDefinitions)2701 for (VersionDefinition &V : Config->VersionDefinitions)
2637 V.NameOff = InX::DynStrTab->addString(V.Name);2702 V.NameOff = In.DynStrTab->addString(V.Name);
26382703
2639 getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;2704 if (OutputSection *Sec = In.DynStrTab->getParent())
2705 getParent()->Link = Sec->SectionIndex;
26402706
2641 // sh_info should be set to the number of definitions. This fact is missed in2707 // sh_info should be set to the number of definitions. This fact is missed in
2642 // documentation, but confirmed by binutils community:2708 // documentation, but confirmed by binutils community:
...@@ -2644,68 +2710,68 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {...@@ -2644,68 +2710,68 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
2644 getParent()->Info = getVerDefNum();2710 getParent()->Info = getVerDefNum();
2645}2711}
26462712
2647template <class ELFT>2713void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
2648void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index,2714 StringRef Name, size_t NameOff) {
2649 StringRef Name, size_t NameOff) {2715 uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
2650 auto *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);2716
2651 Verdef->vd_version = 1;2717 // Write a verdef.
2652 Verdef->vd_cnt = 1;2718 write16(Buf, 1); // vd_version
2653 Verdef->vd_aux = sizeof(Elf_Verdef);2719 write16(Buf + 2, Flags); // vd_flags
2654 Verdef->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);2720 write16(Buf + 4, Index); // vd_ndx
2655 Verdef->vd_flags = (Index == 1 ? VER_FLG_BASE : 0);2721 write16(Buf + 6, 1); // vd_cnt
2656 Verdef->vd_ndx = Index;2722 write32(Buf + 8, hashSysV(Name)); // vd_hash
2657 Verdef->vd_hash = hashSysV(Name);2723 write32(Buf + 12, 20); // vd_aux
26582724 write32(Buf + 16, 28); // vd_next
2659 auto *Verdaux = reinterpret_cast<Elf_Verdaux *>(Buf + sizeof(Elf_Verdef));2725
2660 Verdaux->vda_name = NameOff;2726 // Write a veraux.
2661 Verdaux->vda_next = 0;2727 write32(Buf + 20, NameOff); // vda_name
2728 write32(Buf + 24, 0); // vda_next
2662}2729}
26632730
2664template <class ELFT>2731void VersionDefinitionSection::writeTo(uint8_t *Buf) {
2665void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
2666 writeOne(Buf, 1, getFileDefName(), FileDefNameOff);2732 writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
26672733
2668 for (VersionDefinition &V : Config->VersionDefinitions) {2734 for (VersionDefinition &V : Config->VersionDefinitions) {
2669 Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);2735 Buf += EntrySize;
2670 writeOne(Buf, V.Id, V.Name, V.NameOff);2736 writeOne(Buf, V.Id, V.Name, V.NameOff);
2671 }2737 }
26722738
2673 // Need to terminate the last version definition.2739 // Need to terminate the last version definition.
2674 Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);2740 write32(Buf + 16, 0); // vd_next
2675 Verdef->vd_next = 0;
2676}2741}
26772742
2678template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const {2743size_t VersionDefinitionSection::getSize() const {
2679 return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();2744 return EntrySize * getVerDefNum();
2680}2745}
26812746
2747// .gnu.version is a table where each entry is 2 byte long.
2682template <class ELFT>2748template <class ELFT>
2683VersionTableSection<ELFT>::VersionTableSection()2749VersionTableSection<ELFT>::VersionTableSection()
2684 : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),2750 : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
2685 ".gnu.version") {2751 ".gnu.version") {
2686 this->Entsize = sizeof(Elf_Versym);2752 this->Entsize = 2;
2687}2753}
26882754
2689template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {2755template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
2690 // At the moment of june 2016 GNU docs does not mention that sh_link field2756 // At the moment of june 2016 GNU docs does not mention that sh_link field
2691 // should be set, but Sun docs do. Also readelf relies on this field.2757 // should be set, but Sun docs do. Also readelf relies on this field.
2692 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;2758 getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
2693}2759}
26942760
2695template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {2761template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
2696 return sizeof(Elf_Versym) * (InX::DynSymTab->getSymbols().size() + 1);2762 return (In.DynSymTab->getSymbols().size() + 1) * 2;
2697}2763}
26982764
2699template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {2765template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
2700 auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;2766 Buf += 2;
2701 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {2767 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
2702 OutVersym->vs_index = S.Sym->VersionId;2768 write16(Buf, S.Sym->VersionId);
2703 ++OutVersym;2769 Buf += 2;
2704 }2770 }
2705}2771}
27062772
2707template <class ELFT> bool VersionTableSection<ELFT>::empty() const {2773template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
2708 return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();2774 return !In.VerDef && InX<ELFT>::VerNeed->empty();
2709}2775}
27102776
2711template <class ELFT>2777template <class ELFT>
...@@ -2729,7 +2795,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {...@@ -2729,7 +2795,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
2729 // to create one by adding it to our needed list and creating a dynstr entry2795 // to create one by adding it to our needed list and creating a dynstr entry
2730 // for the soname.2796 // for the soname.
2731 if (File.VerdefMap.empty())2797 if (File.VerdefMap.empty())
2732 Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)});2798 Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
2733 const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];2799 const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
2734 typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];2800 typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
27352801
...@@ -2737,8 +2803,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {...@@ -2737,8 +2803,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
2737 // prepare to create one by allocating a version identifier and creating a2803 // prepare to create one by allocating a version identifier and creating a
2738 // dynstr entry for the version name.2804 // dynstr entry for the version name.
2739 if (NV.Index == 0) {2805 if (NV.Index == 0) {
2740 NV.StrTab = InX::DynStrTab->addString(File.getStringTable().data() +2806 NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() +
2741 Ver->getAux()->vda_name);2807 Ver->getAux()->vda_name);
2742 NV.Index = NextIndex++;2808 NV.Index = NextIndex++;
2743 }2809 }
2744 SS->VersionId = NV.Index;2810 SS->VersionId = NV.Index;
...@@ -2780,7 +2846,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {...@@ -2780,7 +2846,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
2780}2846}
27812847
2782template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {2848template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
2783 getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;2849 if (OutputSection *Sec = In.DynStrTab->getParent())
2850 getParent()->Link = Sec->SectionIndex;
2784 getParent()->Info = Needed.size();2851 getParent()->Info = Needed.size();
2785}2852}
27862853
...@@ -2896,12 +2963,6 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name,...@@ -2896,12 +2963,6 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
2896 return make<MergeNoTailSection>(Name, Type, Flags, Alignment);2963 return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
2897}2964}
28982965
2899// Debug sections may be compressed by zlib. Decompress if exists.
2900void elf::decompressSections() {
2901 parallelForEach(InputSections,
2902 [](InputSectionBase *Sec) { Sec->maybeDecompress(); });
2903}
2904
2905template <class ELFT> void elf::splitSections() {2966template <class ELFT> void elf::splitSections() {
2906 // splitIntoPieces needs to be called on each MergeInputSection2967 // splitIntoPieces needs to be called on each MergeInputSection
2907 // before calling finalizeContents().2968 // before calling finalizeContents().
...@@ -3040,34 +3101,54 @@ bool ThunkSection::assignOffsets() {...@@ -3040,34 +3101,54 @@ bool ThunkSection::assignOffsets() {
3040 return Changed;3101 return Changed;
3041}3102}
30423103
3043InputSection *InX::ARMAttributes;3104// If linking position-dependent code then the table will store the addresses
3044BssSection *InX::Bss;3105// directly in the binary so the section has type SHT_PROGBITS. If linking
3045BssSection *InX::BssRelRo;3106// position-independent code the section has type SHT_NOBITS since it will be
3046BuildIdSection *InX::BuildId;3107// allocated and filled in by the dynamic linker.
3047EhFrameHeader *InX::EhFrameHdr;3108PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
3048EhFrameSection *InX::EhFrame;3109 : SyntheticSection(SHF_ALLOC | SHF_WRITE,
3049SyntheticSection *InX::Dynamic;3110 Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
3050StringTableSection *InX::DynStrTab;3111 ".branch_lt") {}
3051SymbolTableBaseSection *InX::DynSymTab;3112
3052InputSection *InX::Interp;3113void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
3053GdbIndexSection *InX::GdbIndex;3114 assert(Sym.PPC64BranchltIndex == 0xffff);
3054GotSection *InX::Got;3115 Sym.PPC64BranchltIndex = Entries.size();
3055GotPltSection *InX::GotPlt;3116 Entries.push_back(&Sym);
3056GnuHashTableSection *InX::GnuHashTab;3117}
3057HashTableSection *InX::HashTab;3118
3058IgotPltSection *InX::IgotPlt;3119size_t PPC64LongBranchTargetSection::getSize() const {
3059MipsGotSection *InX::MipsGot;3120 return Entries.size() * 8;
3060MipsRldMapSection *InX::MipsRldMap;3121}
3061PltSection *InX::Plt;3122
3062PltSection *InX::Iplt;3123void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
3063RelocationBaseSection *InX::RelaDyn;3124 assert(Target->GotPltEntrySize == 8);
3064RelrBaseSection *InX::RelrDyn;3125 // If linking non-pic we have the final addresses of the targets and they get
3065RelocationBaseSection *InX::RelaPlt;3126 // written to the table directly. For pic the dynamic linker will allocate
3066RelocationBaseSection *InX::RelaIplt;3127 // the section and fill it it.
3067StringTableSection *InX::ShStrTab;3128 if (Config->Pic)
3068StringTableSection *InX::StrTab;3129 return;
3069SymbolTableBaseSection *InX::SymTab;3130
3070SymtabShndxSection *InX::SymTabShndx;3131 for (const Symbol *Sym : Entries) {
3132 assert(Sym->getVA());
3133 // Need calls to branch to the local entry-point since a long-branch
3134 // must be a local-call.
3135 write64(Buf,
3136 Sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(Sym->StOther));
3137 Buf += Target->GotPltEntrySize;
3138 }
3139}
3140
3141bool PPC64LongBranchTargetSection::empty() const {
3142 // `removeUnusedSyntheticSections()` is called before thunk allocation which
3143 // is too early to determine if this section will be empty or not. We need
3144 // Finalized to keep the section alive until after thunk creation. Finalized
3145 // only gets set to true once `finalizeSections()` is called after thunk
3146 // creation. Becuase of this, if we don't create any long-branch thunks we end
3147 // up with an empty .branch_lt section in the binary.
3148 return Finalized && Entries.empty();
3149}
3150
3151InStruct elf::In;
30713152
3072template GdbIndexSection *GdbIndexSection::create<ELF32LE>();3153template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
3073template GdbIndexSection *GdbIndexSection::create<ELF32BE>();3154template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
...@@ -3143,8 +3224,3 @@ template class elf::VersionNeedSection<ELF32LE>;...@@ -3143,8 +3224,3 @@ template class elf::VersionNeedSection<ELF32LE>;
3143template class elf::VersionNeedSection<ELF32BE>;3224template class elf::VersionNeedSection<ELF32BE>;
3144template class elf::VersionNeedSection<ELF64LE>;3225template class elf::VersionNeedSection<ELF64LE>;
3145template class elf::VersionNeedSection<ELF64BE>;3226template class elf::VersionNeedSection<ELF64BE>;
3146
3147template class elf::VersionDefinitionSection<ELF32LE>;
3148template class elf::VersionDefinitionSection<ELF32BE>;
3149template class elf::VersionDefinitionSection<ELF64LE>;
3150template class elf::VersionDefinitionSection<ELF64BE>;
deps/lld/ELF/SyntheticSections.h+80-57
...@@ -21,8 +21,8 @@...@@ -21,8 +21,8 @@
21#ifndef LLD_ELF_SYNTHETIC_SECTION_H21#ifndef LLD_ELF_SYNTHETIC_SECTION_H
22#define LLD_ELF_SYNTHETIC_SECTION_H22#define LLD_ELF_SYNTHETIC_SECTION_H
2323
24#include "DWARF.h"
24#include "EhFrame.h"25#include "EhFrame.h"
25#include "GdbIndex.h"
26#include "InputSection.h"26#include "InputSection.h"
27#include "llvm/ADT/MapVector.h"27#include "llvm/ADT/MapVector.h"
28#include "llvm/MC/StringTableBuilder.h"28#include "llvm/MC/StringTableBuilder.h"
...@@ -50,8 +50,6 @@ public:...@@ -50,8 +50,6 @@ public:
50 // If the section has the SHF_ALLOC flag and the size may be changed if50 // If the section has the SHF_ALLOC flag and the size may be changed if
51 // thunks are added, update the section size.51 // thunks are added, update the section size.
52 virtual bool updateAllocSize() { return false; }52 virtual bool updateAllocSize() { return false; }
53 // If any additional finalization of contents are needed post thunk creation.
54 virtual void postThunkContents() {}
55 virtual bool empty() const { return false; }53 virtual bool empty() const { return false; }
5654
57 static bool classof(const SectionBase *D) {55 static bool classof(const SectionBase *D) {
...@@ -137,6 +135,15 @@ protected:...@@ -137,6 +135,15 @@ protected:
137 uint64_t Size = 0;135 uint64_t Size = 0;
138};136};
139137
138// .note.GNU-stack section.
139class GnuStackSection : public SyntheticSection {
140public:
141 GnuStackSection()
142 : SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
143 void writeTo(uint8_t *Buf) override {}
144 size_t getSize() const override { return 0; }
145};
146
140// .note.gnu.build-id section.147// .note.gnu.build-id section.
141class BuildIdSection : public SyntheticSection {148class BuildIdSection : public SyntheticSection {
142 // First 16 bytes are a header.149 // First 16 bytes are a header.
...@@ -163,7 +170,9 @@ private:...@@ -163,7 +170,9 @@ private:
163class BssSection final : public SyntheticSection {170class BssSection final : public SyntheticSection {
164public:171public:
165 BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);172 BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);
166 void writeTo(uint8_t *) override {}173 void writeTo(uint8_t *) override {
174 llvm_unreachable("unexpected writeTo() call for SHT_NOBITS section");
175 }
167 bool empty() const override { return getSize() == 0; }176 bool empty() const override { return getSize() == 0; }
168 size_t getSize() const override { return Size; }177 size_t getSize() const override { return Size; }
169178
...@@ -300,8 +309,6 @@ private:...@@ -300,8 +309,6 @@ private:
300309
301 uint64_t Size = 0;310 uint64_t Size = 0;
302311
303 size_t LocalEntriesNum = 0;
304
305 // Symbol and addend.312 // Symbol and addend.
306 typedef std::pair<Symbol *, int64_t> GotEntry;313 typedef std::pair<Symbol *, int64_t> GotEntry;
307314
...@@ -333,8 +340,6 @@ private:...@@ -333,8 +340,6 @@ private:
333 size_t getPageEntriesNum() const;340 size_t getPageEntriesNum() const;
334 // Number of entries require 16-bit index to access.341 // Number of entries require 16-bit index to access.
335 size_t getIndexedEntriesNum() const;342 size_t getIndexedEntriesNum() const;
336
337 bool isOverflow() const;
338 };343 };
339344
340 // Container of GOT created for each input file.345 // Container of GOT created for each input file.
...@@ -529,6 +534,7 @@ struct RelativeReloc {...@@ -529,6 +534,7 @@ struct RelativeReloc {
529class RelrBaseSection : public SyntheticSection {534class RelrBaseSection : public SyntheticSection {
530public:535public:
531 RelrBaseSection();536 RelrBaseSection();
537 bool empty() const override { return Relocs.empty(); }
532 std::vector<RelativeReloc> Relocs;538 std::vector<RelativeReloc> Relocs;
533};539};
534540
...@@ -561,7 +567,6 @@ class SymbolTableBaseSection : public SyntheticSection {...@@ -561,7 +567,6 @@ class SymbolTableBaseSection : public SyntheticSection {
561public:567public:
562 SymbolTableBaseSection(StringTableSection &StrTabSec);568 SymbolTableBaseSection(StringTableSection &StrTabSec);
563 void finalizeContents() override;569 void finalizeContents() override;
564 void postThunkContents() override;
565 size_t getSize() const override { return getNumSymbols() * Entsize; }570 size_t getSize() const override { return getNumSymbols() * Entsize; }
566 void addSymbol(Symbol *Sym);571 void addSymbol(Symbol *Sym);
567 unsigned getNumSymbols() const { return Symbols.size() + 1; }572 unsigned getNumSymbols() const { return Symbols.size() + 1; }
...@@ -569,6 +574,8 @@ public:...@@ -569,6 +574,8 @@ public:
569 ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }574 ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
570575
571protected:576protected:
577 void sortSymTabSymbols();
578
572 // A vector of symbols and their string table offsets.579 // A vector of symbols and their string table offsets.
573 std::vector<SymbolTableEntry> Symbols;580 std::vector<SymbolTableEntry> Symbols;
574581
...@@ -612,7 +619,8 @@ public:...@@ -612,7 +619,8 @@ public:
612 void addSymbols(std::vector<SymbolTableEntry> &Symbols);619 void addSymbols(std::vector<SymbolTableEntry> &Symbols);
613620
614private:621private:
615 enum { Shift2 = 6 };622 // See the comment in writeBloomFilter.
623 enum { Shift2 = 26 };
616624
617 void writeBloomFilter(uint8_t *Buf);625 void writeBloomFilter(uint8_t *Buf);
618 void writeHashTable(uint8_t *Buf);626 void writeHashTable(uint8_t *Buf);
...@@ -652,13 +660,13 @@ public:...@@ -652,13 +660,13 @@ public:
652 size_t getSize() const override;660 size_t getSize() const override;
653 bool empty() const override { return Entries.empty(); }661 bool empty() const override { return Entries.empty(); }
654 void addSymbols();662 void addSymbols();
655
656 template <class ELFT> void addEntry(Symbol &Sym);663 template <class ELFT> void addEntry(Symbol &Sym);
657664
665 size_t HeaderSize;
666
658private:667private:
659 unsigned getPltRelocOff() const;668 unsigned getPltRelocOff() const;
660 std::vector<std::pair<const Symbol *, unsigned>> Entries;669 std::vector<std::pair<const Symbol *, unsigned>> Entries;
661 size_t HeaderSize;
662 bool IsIplt;670 bool IsIplt;
663};671};
664672
...@@ -676,9 +684,9 @@ public:...@@ -676,9 +684,9 @@ public:
676 uint64_t CuLength;684 uint64_t CuLength;
677 };685 };
678686
679 struct NameTypeEntry {687 struct NameAttrEntry {
680 llvm::CachedHashStringRef Name;688 llvm::CachedHashStringRef Name;
681 uint32_t Type;689 uint32_t CuIndexAndAttrs;
682 };690 };
683691
684 struct GdbChunk {692 struct GdbChunk {
...@@ -748,11 +756,7 @@ public:...@@ -748,11 +756,7 @@ public:
748// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.756// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
749// The section shall contain an array of Elf_Verdef structures, optionally757// The section shall contain an array of Elf_Verdef structures, optionally
750// followed by an array of Elf_Verdaux structures.758// followed by an array of Elf_Verdaux structures.
751template <class ELFT>
752class VersionDefinitionSection final : public SyntheticSection {759class VersionDefinitionSection final : public SyntheticSection {
753 typedef typename ELFT::Verdef Elf_Verdef;
754 typedef typename ELFT::Verdaux Elf_Verdaux;
755
756public:760public:
757 VersionDefinitionSection();761 VersionDefinitionSection();
758 void finalizeContents() override;762 void finalizeContents() override;
...@@ -760,6 +764,7 @@ public:...@@ -760,6 +764,7 @@ public:
760 void writeTo(uint8_t *Buf) override;764 void writeTo(uint8_t *Buf) override;
761765
762private:766private:
767 enum { EntrySize = 28 };
763 void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);768 void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
764769
765 unsigned FileDefNameOff;770 unsigned FileDefNameOff;
...@@ -773,8 +778,6 @@ private:...@@ -773,8 +778,6 @@ private:
773// the own object or in any of the dependencies.778// the own object or in any of the dependencies.
774template <class ELFT>779template <class ELFT>
775class VersionTableSection final : public SyntheticSection {780class VersionTableSection final : public SyntheticSection {
776 typedef typename ELFT::Versym Elf_Versym;
777
778public:781public:
779 VersionTableSection();782 VersionTableSection();
780 void finalizeContents() override;783 void finalizeContents() override;
...@@ -964,9 +967,27 @@ private:...@@ -964,9 +967,27 @@ private:
964 size_t Size = 0;967 size_t Size = 0;
965};968};
966969
970// This section is used to store the addresses of functions that are called
971// in range-extending thunks on PowerPC64. When producing position dependant
972// code the addresses are link-time constants and the table is written out to
973// the binary. When producing position-dependant code the table is allocated and
974// filled in by the dynamic linker.
975class PPC64LongBranchTargetSection final : public SyntheticSection {
976public:
977 PPC64LongBranchTargetSection();
978 void addEntry(Symbol &Sym);
979 size_t getSize() const override;
980 void writeTo(uint8_t *Buf) override;
981 bool empty() const override;
982 void finalizeContents() override { Finalized = true; }
983
984private:
985 std::vector<const Symbol *> Entries;
986 bool Finalized = false;
987};
988
967InputSection *createInterpSection();989InputSection *createInterpSection();
968MergeInputSection *createCommentSection();990MergeInputSection *createCommentSection();
969void decompressSections();
970template <class ELFT> void splitSections();991template <class ELFT> void splitSections();
971void mergeSections();992void mergeSections();
972993
...@@ -974,46 +995,48 @@ Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,...@@ -974,46 +995,48 @@ Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
974 uint64_t Size, InputSectionBase &Section);995 uint64_t Size, InputSectionBase &Section);
975996
976// Linker generated sections which can be used as inputs.997// Linker generated sections which can be used as inputs.
977struct InX {998struct InStruct {
978 static InputSection *ARMAttributes;999 InputSection *ARMAttributes;
979 static BssSection *Bss;1000 BssSection *Bss;
980 static BssSection *BssRelRo;1001 BssSection *BssRelRo;
981 static BuildIdSection *BuildId;1002 BuildIdSection *BuildId;
982 static EhFrameHeader *EhFrameHdr;1003 EhFrameHeader *EhFrameHdr;
983 static EhFrameSection *EhFrame;1004 EhFrameSection *EhFrame;
984 static SyntheticSection *Dynamic;1005 SyntheticSection *Dynamic;
985 static StringTableSection *DynStrTab;1006 StringTableSection *DynStrTab;
986 static SymbolTableBaseSection *DynSymTab;1007 SymbolTableBaseSection *DynSymTab;
987 static GnuHashTableSection *GnuHashTab;1008 GnuHashTableSection *GnuHashTab;
988 static HashTableSection *HashTab;1009 HashTableSection *HashTab;
989 static InputSection *Interp;1010 InputSection *Interp;
990 static GdbIndexSection *GdbIndex;1011 GdbIndexSection *GdbIndex;
991 static GotSection *Got;1012 GotSection *Got;
992 static GotPltSection *GotPlt;1013 GotPltSection *GotPlt;
993 static IgotPltSection *IgotPlt;1014 IgotPltSection *IgotPlt;
994 static MipsGotSection *MipsGot;1015 PPC64LongBranchTargetSection *PPC64LongBranchTarget;
995 static MipsRldMapSection *MipsRldMap;1016 MipsGotSection *MipsGot;
996 static PltSection *Plt;1017 MipsRldMapSection *MipsRldMap;
997 static PltSection *Iplt;1018 PltSection *Plt;
998 static RelocationBaseSection *RelaDyn;1019 PltSection *Iplt;
999 static RelrBaseSection *RelrDyn;1020 RelocationBaseSection *RelaDyn;
1000 static RelocationBaseSection *RelaPlt;1021 RelrBaseSection *RelrDyn;
1001 static RelocationBaseSection *RelaIplt;1022 RelocationBaseSection *RelaPlt;
1002 static StringTableSection *ShStrTab;1023 RelocationBaseSection *RelaIplt;
1003 static StringTableSection *StrTab;1024 StringTableSection *ShStrTab;
1004 static SymbolTableBaseSection *SymTab;1025 StringTableSection *StrTab;
1005 static SymtabShndxSection* SymTabShndx;1026 SymbolTableBaseSection *SymTab;
1006};1027 SymtabShndxSection *SymTabShndx;
10071028 VersionDefinitionSection *VerDef;
1008template <class ELFT> struct In {1029};
1009 static VersionDefinitionSection<ELFT> *VerDef;1030
1031extern InStruct In;
1032
1033template <class ELFT> struct InX {
1010 static VersionTableSection<ELFT> *VerSym;1034 static VersionTableSection<ELFT> *VerSym;
1011 static VersionNeedSection<ELFT> *VerNeed;1035 static VersionNeedSection<ELFT> *VerNeed;
1012};1036};
10131037
1014template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;1038template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
1015template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;1039template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
1016template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
1017} // namespace elf1040} // namespace elf
1018} // namespace lld1041} // namespace lld
10191042
deps/lld/ELF/Target.cpp+8-5
...@@ -73,12 +73,16 @@ TargetInfo *elf::getTarget() {...@@ -73,12 +73,16 @@ TargetInfo *elf::getTarget() {
73 case ELF64BEKind:73 case ELF64BEKind:
74 return getMipsTargetInfo<ELF64BE>();74 return getMipsTargetInfo<ELF64BE>();
75 default:75 default:
76 fatal("unsupported MIPS target");76 llvm_unreachable("unsupported MIPS target");
77 }77 }
78 case EM_MSP430:
79 return getMSP430TargetInfo();
78 case EM_PPC:80 case EM_PPC:
79 return getPPCTargetInfo();81 return getPPCTargetInfo();
80 case EM_PPC64:82 case EM_PPC64:
81 return getPPC64TargetInfo();83 return getPPC64TargetInfo();
84 case EM_RISCV:
85 return getRISCVTargetInfo();
82 case EM_SPARCV9:86 case EM_SPARCV9:
83 return getSPARCV9TargetInfo();87 return getSPARCV9TargetInfo();
84 case EM_X86_64:88 case EM_X86_64:
...@@ -86,7 +90,7 @@ TargetInfo *elf::getTarget() {...@@ -86,7 +90,7 @@ TargetInfo *elf::getTarget() {
86 return getX32TargetInfo();90 return getX32TargetInfo();
87 return getX86_64TargetInfo();91 return getX86_64TargetInfo();
88 }92 }
89 fatal("unknown target machine");93 llvm_unreachable("unknown target machine");
90}94}
9195
92template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {96template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {
...@@ -130,12 +134,11 @@ bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,...@@ -130,12 +134,11 @@ bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
130 return false;134 return false;
131}135}
132136
133bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc,137bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
134 uint8_t *End) const {138 uint8_t StOther) const {
135 llvm_unreachable("Target doesn't support split stacks.");139 llvm_unreachable("Target doesn't support split stacks.");
136}140}
137141
138
139bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {142bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
140 return true;143 return true;
141}144}
deps/lld/ELF/Target.h+36-28
...@@ -13,6 +13,8 @@...@@ -13,6 +13,8 @@
13#include "InputSection.h"13#include "InputSection.h"
14#include "lld/Common/ErrorHandler.h"14#include "lld/Common/ErrorHandler.h"
15#include "llvm/Object/ELF.h"15#include "llvm/Object/ELF.h"
16#include "llvm/Support/MathExtras.h"
17#include <array>
1618
17namespace lld {19namespace lld {
18std::string toString(elf::RelType Type);20std::string toString(elf::RelType Type);
...@@ -43,10 +45,6 @@ public:...@@ -43,10 +45,6 @@ public:
43 virtual void addPltHeaderSymbols(InputSection &IS) const {}45 virtual void addPltHeaderSymbols(InputSection &IS) const {}
44 virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}46 virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}
4547
46 unsigned getPltEntryOffset(unsigned Index) const {
47 return Index * PltEntrySize + PltHeaderSize;
48 }
49
50 // Returns true if a relocation only uses the low bits of a value such that48 // Returns true if a relocation only uses the low bits of a value such that
51 // all those bits are in the same page. For example, if the relocation49 // all those bits are in the same page. For example, if the relocation
52 // only uses the low 12 bits in a system with 4k pages. If this is true, the50 // only uses the low 12 bits in a system with 4k pages. If this is true, the
...@@ -60,11 +58,18 @@ public:...@@ -60,11 +58,18 @@ public:
60 const InputFile *File, uint64_t BranchAddr,58 const InputFile *File, uint64_t BranchAddr,
61 const Symbol &S) const;59 const Symbol &S) const;
6260
61 // On systems with range extensions we place collections of Thunks at
62 // regular spacings that enable the majority of branches reach the Thunks.
63 // a value of 0 means range extension thunks are not supported.
64 virtual uint32_t getThunkSectionSpacing() const { return 0; }
65
63 // The function with a prologue starting at Loc was compiled with66 // The function with a prologue starting at Loc was compiled with
64 // -fsplit-stack and it calls a function compiled without. Adjust the prologue67 // -fsplit-stack and it calls a function compiled without. Adjust the prologue
65 // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.68 // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
66 virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc,69 // The symbols st_other flags are needed on PowerPC64 for determining the
67 uint8_t *End) const;70 // offset to the split-stack prologue.
71 virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
72 uint8_t StOther) const;
6873
69 // Return true if we can reach Dst from Src with Relocation RelocType74 // Return true if we can reach Dst from Src with Relocation RelocType
70 virtual bool inBranchRange(RelType Type, uint64_t Src,75 virtual bool inBranchRange(RelType Type, uint64_t Src,
...@@ -87,12 +92,9 @@ public:...@@ -87,12 +92,9 @@ public:
87 // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.92 // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
88 bool GotBaseSymInGotPlt = true;93 bool GotBaseSymInGotPlt = true;
8994
90 // On systems with range extensions we place collections of Thunks at
91 // regular spacings that enable the majority of branches reach the Thunks.
92 uint32_t ThunkSectionSpacing = 0;
93
94 RelType CopyRel;95 RelType CopyRel;
95 RelType GotRel;96 RelType GotRel;
97 RelType NoneRel;
96 RelType PltRel;98 RelType PltRel;
97 RelType RelativeRel;99 RelType RelativeRel;
98 RelType IRelativeRel;100 RelType IRelativeRel;
...@@ -112,20 +114,16 @@ public:...@@ -112,20 +114,16 @@ public:
112 // On PPC ELF V2 abi, the first entry in the .got is the .TOC.114 // On PPC ELF V2 abi, the first entry in the .got is the .TOC.
113 unsigned GotHeaderEntriesNum = 0;115 unsigned GotHeaderEntriesNum = 0;
114116
115 // For TLS variant 1, the TCB is a fixed size specified by the Target.
116 // For variant 2, the TCB is an unspecified size.
117 // Set to 0 for variant 2.
118 unsigned TcbSize = 0;
119
120 // Set to the offset (in bytes) that the thread pointer is initialized to
121 // point to, relative to the start of the thread local storage.
122 unsigned TlsTpOffset = 0;
123
124 bool NeedsThunks = false;117 bool NeedsThunks = false;
125118
126 // A 4-byte field corresponding to one or more trap instructions, used to pad119 // A 4-byte field corresponding to one or more trap instructions, used to pad
127 // executable OutputSections.120 // executable OutputSections.
128 uint32_t TrapInstr = 0;121 std::array<uint8_t, 4> TrapInstr;
122
123 // If a target needs to rewrite calls to __morestack to instead call
124 // __morestack_non_split when a split-stack enabled caller calls a
125 // non-split-stack callee this will return true. Otherwise returns false.
126 bool NeedsMoreStackNonSplit = true;
129127
130 virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,128 virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
131 RelExpr Expr) const;129 RelExpr Expr) const;
...@@ -148,8 +146,10 @@ TargetInfo *getAMDGPUTargetInfo();...@@ -148,8 +146,10 @@ TargetInfo *getAMDGPUTargetInfo();
148TargetInfo *getARMTargetInfo();146TargetInfo *getARMTargetInfo();
149TargetInfo *getAVRTargetInfo();147TargetInfo *getAVRTargetInfo();
150TargetInfo *getHexagonTargetInfo();148TargetInfo *getHexagonTargetInfo();
149TargetInfo *getMSP430TargetInfo();
151TargetInfo *getPPC64TargetInfo();150TargetInfo *getPPC64TargetInfo();
152TargetInfo *getPPCTargetInfo();151TargetInfo *getPPCTargetInfo();
152TargetInfo *getRISCVTargetInfo();
153TargetInfo *getSPARCV9TargetInfo();153TargetInfo *getSPARCV9TargetInfo();
154TargetInfo *getX32TargetInfo();154TargetInfo *getX32TargetInfo();
155TargetInfo *getX86TargetInfo();155TargetInfo *getX86TargetInfo();
...@@ -168,6 +168,15 @@ static inline std::string getErrorLocation(const uint8_t *Loc) {...@@ -168,6 +168,15 @@ static inline std::string getErrorLocation(const uint8_t *Loc) {
168 return getErrorPlace(Loc).Loc;168 return getErrorPlace(Loc).Loc;
169}169}
170170
171// In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first is
172// a global entry point (GEP) which typically is used to intiailzie the TOC
173// pointer in general purpose register 2. The second is a local entry
174// point (LEP) which bypasses the TOC pointer initialization code. The
175// offset between GEP and LEP is encoded in a function's st_other flags.
176// This function will return the offset (in bytes) from the global entry-point
177// to the local entry-point.
178unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
179
171uint64_t getPPC64TocBase();180uint64_t getPPC64TocBase();
172uint64_t getAArch64Page(uint64_t Expr);181uint64_t getAArch64Page(uint64_t Expr);
173182
...@@ -184,19 +193,18 @@ static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,...@@ -184,19 +193,18 @@ static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,
184 Hint = "; consider recompiling with -fdebug-types-section to reduce size "193 Hint = "; consider recompiling with -fdebug-types-section to reduce size "
185 "of debug sections";194 "of debug sections";
186195
187 error(ErrPlace.Loc + "relocation " + lld::toString(Type) +196 errorOrWarn(ErrPlace.Loc + "relocation " + lld::toString(Type) +
188 " out of range: " + V.str() + " is not in [" + Twine(Min).str() + ", " +197 " out of range: " + V.str() + " is not in [" + Twine(Min).str() +
189 Twine(Max).str() + "]" + Hint);198 ", " + Twine(Max).str() + "]" + Hint);
190}199}
191200
192// Sign-extend Nth bit all the way to MSB.201inline unsigned getPltEntryOffset(unsigned Idx) {
193inline int64_t signExtend(uint64_t V, int N) {202 return Target->PltHeaderSize + Target->PltEntrySize * Idx;
194 return int64_t(V << (64 - N)) >> (64 - N);
195}203}
196204
197// Make sure that V can be represented as an N bit signed integer.205// Make sure that V can be represented as an N bit signed integer.
198inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) {206inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) {
199 if (V != signExtend(V, N))207 if (V != llvm::SignExtend64(V, N))
200 reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));208 reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));
201}209}
202210
...@@ -210,7 +218,7 @@ inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {...@@ -210,7 +218,7 @@ inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
210inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {218inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
211 // For the error message we should cast V to a signed integer so that error219 // For the error message we should cast V to a signed integer so that error
212 // messages show a small negative value rather than an extremely large one220 // messages show a small negative value rather than an extremely large one
213 if (V != (uint64_t)signExtend(V, N) && (V >> N) != 0)221 if (V != (uint64_t)llvm::SignExtend64(V, N) && (V >> N) != 0)
214 reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),222 reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
215 llvm::maxIntN(N));223 llvm::maxIntN(N));
216}224}
deps/lld/ELF/Thunks.cpp+280-24
...@@ -159,6 +159,50 @@ public:...@@ -159,6 +159,50 @@ public:
159 void addSymbols(ThunkSection &IS) override;159 void addSymbols(ThunkSection &IS) override;
160};160};
161161
162// Implementations of Thunks for older Arm architectures that do not support
163// the movt/movw instructions. These thunks require at least Architecture v5
164// as used on processors such as the Arm926ej-s. There are no Thumb entry
165// points as there is no Thumb branch instruction on these architecture that
166// can result in a thunk
167class ARMV5ABSLongThunk final : public ARMThunk {
168public:
169 ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
170
171 uint32_t sizeLong() override { return 8; }
172 void writeLong(uint8_t *Buf) override;
173 void addSymbols(ThunkSection &IS) override;
174 bool isCompatibleWith(uint32_t RelocType) const override;
175};
176
177class ARMV5PILongThunk final : public ARMThunk {
178public:
179 ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
180
181 uint32_t sizeLong() override { return 16; }
182 void writeLong(uint8_t *Buf) override;
183 void addSymbols(ThunkSection &IS) override;
184 bool isCompatibleWith(uint32_t RelocType) const override;
185};
186
187// Implementations of Thunks for Arm v6-M. Only Thumb instructions are permitted
188class ThumbV6MABSLongThunk final : public ThumbThunk {
189public:
190 ThumbV6MABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
191
192 uint32_t sizeLong() override { return 12; }
193 void writeLong(uint8_t *Buf) override;
194 void addSymbols(ThunkSection &IS) override;
195};
196
197class ThumbV6MPILongThunk final : public ThumbThunk {
198public:
199 ThumbV6MPILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
200
201 uint32_t sizeLong() override { return 16; }
202 void writeLong(uint8_t *Buf) override;
203 void addSymbols(ThunkSection &IS) override;
204};
205
162// MIPS LA25 thunk206// MIPS LA25 thunk
163class MipsThunk final : public Thunk {207class MipsThunk final : public Thunk {
164public:208public:
...@@ -209,6 +253,46 @@ public:...@@ -209,6 +253,46 @@ public:
209 void addSymbols(ThunkSection &IS) override;253 void addSymbols(ThunkSection &IS) override;
210};254};
211255
256// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte
257// alignment. This gives a possible 26 bits of 'reach'. If the call offset is
258// larger then that we need to emit a long-branch thunk. The target address
259// of the callee is stored in a table to be accessed TOC-relative. Since the
260// call must be local (a non-local call will have a PltCallStub instead) the
261// table stores the address of the callee's local entry point. For
262// position-independent code a corresponding relative dynamic relocation is
263// used.
264class PPC64LongBranchThunk : public Thunk {
265public:
266 uint32_t size() override { return 16; }
267 void writeTo(uint8_t *Buf) override;
268 void addSymbols(ThunkSection &IS) override;
269
270protected:
271 PPC64LongBranchThunk(Symbol &Dest) : Thunk(Dest) {}
272};
273
274class PPC64PILongBranchThunk final : public PPC64LongBranchThunk {
275public:
276 PPC64PILongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
277 assert(!Dest.IsPreemptible);
278 if (Dest.isInPPC64Branchlt())
279 return;
280
281 In.PPC64LongBranchTarget->addEntry(Dest);
282 In.RelaDyn->addReloc({Target->RelativeRel, In.PPC64LongBranchTarget,
283 Dest.getPPC64LongBranchOffset(), true, &Dest,
284 getPPC64GlobalEntryToLocalEntryOffset(Dest.StOther)});
285 }
286};
287
288class PPC64PDLongBranchThunk final : public PPC64LongBranchThunk {
289public:
290 PPC64PDLongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
291 if (!Dest.isInPPC64Branchlt())
292 In.PPC64LongBranchTarget->addEntry(Dest);
293 }
294};
295
212} // end anonymous namespace296} // end anonymous namespace
213297
214Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,298Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
...@@ -395,12 +479,12 @@ void ARMV7PILongThunk::writeLong(uint8_t *Buf) {...@@ -395,12 +479,12 @@ void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
395 const uint8_t Data[] = {479 const uint8_t Data[] = {
396 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)480 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)
397 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)481 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)
398 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc482 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
399 0x1c, 0xff, 0x2f, 0xe1, // bx r12483 0x1c, 0xff, 0x2f, 0xe1, // bx ip
400 };484 };
401 uint64_t S = getARMThunkDestVA(Destination);485 uint64_t S = getARMThunkDestVA(Destination);
402 uint64_t P = getThunkTargetSym()->getVA();486 uint64_t P = getThunkTargetSym()->getVA();
403 uint64_t Offset = S - P - 16;487 int64_t Offset = S - P - 16;
404 memcpy(Buf, Data, sizeof(Data));488 memcpy(Buf, Data, sizeof(Data));
405 Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);489 Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
406 Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);490 Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
...@@ -416,12 +500,12 @@ void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {...@@ -416,12 +500,12 @@ void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
416 const uint8_t Data[] = {500 const uint8_t Data[] = {
417 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)501 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
418 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)502 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
419 0xfc, 0x44, // L1: add r12, pc503 0xfc, 0x44, // L1: add ip, pc
420 0x60, 0x47, // bx r12504 0x60, 0x47, // bx ip
421 };505 };
422 uint64_t S = getARMThunkDestVA(Destination);506 uint64_t S = getARMThunkDestVA(Destination);
423 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;507 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
424 uint64_t Offset = S - P - 12;508 int64_t Offset = S - P - 12;
425 memcpy(Buf, Data, sizeof(Data));509 memcpy(Buf, Data, sizeof(Data));
426 Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);510 Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
427 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);511 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
...@@ -433,6 +517,102 @@ void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {...@@ -433,6 +517,102 @@ void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
433 addSymbol("$t", STT_NOTYPE, 0, IS);517 addSymbol("$t", STT_NOTYPE, 0, IS);
434}518}
435519
520void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
521 const uint8_t Data[] = {
522 0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc,#-4] ; L1
523 0x00, 0x00, 0x00, 0x00, // L1: .word S
524 };
525 memcpy(Buf, Data, sizeof(Data));
526 Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
527}
528
529void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
530 addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
531 STT_FUNC, 0, IS);
532 addSymbol("$a", STT_NOTYPE, 0, IS);
533 addSymbol("$d", STT_NOTYPE, 4, IS);
534}
535
536bool ARMV5ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
537 // Thumb branch relocations can't use BLX
538 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
539}
540
541void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
542 const uint8_t Data[] = {
543 0x04, 0xc0, 0x9f, 0xe5, // P: ldr ip, [pc,#4] ; L2
544 0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
545 0x1c, 0xff, 0x2f, 0xe1, // bx ip
546 0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
547 };
548 uint64_t S = getARMThunkDestVA(Destination);
549 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
550 memcpy(Buf, Data, sizeof(Data));
551 Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
552}
553
554void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
555 addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
556 0, IS);
557 addSymbol("$a", STT_NOTYPE, 0, IS);
558 addSymbol("$d", STT_NOTYPE, 12, IS);
559}
560
561bool ARMV5PILongThunk::isCompatibleWith(uint32_t RelocType) const {
562 // Thumb branch relocations can't use BLX
563 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
564}
565
566void ThumbV6MABSLongThunk::writeLong(uint8_t *Buf) {
567 // Most Thumb instructions cannot access the high registers r8 - r15. As the
568 // only register we can corrupt is r12 we must instead spill a low register
569 // to the stack to use as a scratch register. We push r1 even though we
570 // don't need to get some space to use for the return address.
571 const uint8_t Data[] = {
572 0x03, 0xb4, // push {r0, r1} ; Obtain scratch registers
573 0x01, 0x48, // ldr r0, [pc, #4] ; L1
574 0x01, 0x90, // str r0, [sp, #4] ; SP + 4 = S
575 0x01, 0xbd, // pop {r0, pc} ; restore r0 and branch to dest
576 0x00, 0x00, 0x00, 0x00 // L1: .word S
577 };
578 uint64_t S = getARMThunkDestVA(Destination);
579 memcpy(Buf, Data, sizeof(Data));
580 Target->relocateOne(Buf + 8, R_ARM_ABS32, S);
581}
582
583void ThumbV6MABSLongThunk::addSymbols(ThunkSection &IS) {
584 addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + Destination.getName()),
585 STT_FUNC, 1, IS);
586 addSymbol("$t", STT_NOTYPE, 0, IS);
587 addSymbol("$d", STT_NOTYPE, 8, IS);
588}
589
590void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
591 // Most Thumb instructions cannot access the high registers r8 - r15. As the
592 // only register we can corrupt is ip (r12) we must instead spill a low
593 // register to the stack to use as a scratch register.
594 const uint8_t Data[] = {
595 0x01, 0xb4, // P: push {r0} ; Obtain scratch register
596 0x02, 0x48, // ldr r0, [pc, #8] ; L2
597 0x84, 0x46, // mov ip, r0 ; high to low register
598 0x01, 0xbc, // pop {r0} ; restore scratch register
599 0xe7, 0x44, // L1: add pc, ip ; transfer control
600 0xc0, 0x46, // nop ; pad to 4-byte boundary
601 0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
602 };
603 uint64_t S = getARMThunkDestVA(Destination);
604 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
605 memcpy(Buf, Data, sizeof(Data));
606 Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
607}
608
609void ThumbV6MPILongThunk::addSymbols(ThunkSection &IS) {
610 addSymbol(Saver.save("__Thumbv6MPILongThunk_" + Destination.getName()),
611 STT_FUNC, 1, IS);
612 addSymbol("$t", STT_NOTYPE, 0, IS);
613 addSymbol("$d", STT_NOTYPE, 12, IS);
614}
615
436// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.616// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
437void MipsThunk::writeTo(uint8_t *Buf) {617void MipsThunk::writeTo(uint8_t *Buf) {
438 uint64_t S = Destination.getVA();618 uint64_t S = Destination.getVA();
...@@ -502,17 +682,21 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const {...@@ -502,17 +682,21 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
502 return dyn_cast<InputSection>(DR.Section);682 return dyn_cast<InputSection>(DR.Section);
503}683}
504684
505void PPC64PltCallStub::writeTo(uint8_t *Buf) {685static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
506 int64_t Off = Destination.getGotPltVA() - getPPC64TocBase();686 uint16_t OffHa = (Offset + 0x8000) >> 16;
507 // Need to add 0x8000 to offset to account for the low bits being signed.687 uint16_t OffLo = Offset & 0xffff;
508 uint16_t OffHa = (Off + 0x8000) >> 16;
509 uint16_t OffLo = Off;
510688
511 write32(Buf + 0, 0xf8410018); // std r2,24(r1)689 write32(Buf + 0, 0x3d820000 | OffHa); // addis r12, r2, OffHa
512 write32(Buf + 4, 0x3d820000 | OffHa); // addis r12,r2, X@plt@to@ha690 write32(Buf + 4, 0xe98c0000 | OffLo); // ld r12, OffLo(r12)
513 write32(Buf + 8, 0xe98c0000 | OffLo); // ld r12,X@plt@toc@l(r12)691 write32(Buf + 8, 0x7d8903a6); // mtctr r12
514 write32(Buf + 12, 0x7d8903a6); // mtctr r12692 write32(Buf + 12, 0x4e800420); // bctr
515 write32(Buf + 16, 0x4e800420); // bctr693}
694
695void PPC64PltCallStub::writeTo(uint8_t *Buf) {
696 int64_t Offset = Destination.getGotPltVA() - getPPC64TocBase();
697 // Save the TOC pointer to the save-slot reserved in the call frame.
698 write32(Buf + 0, 0xf8410018); // std r2,24(r1)
699 writePPCLoadAndBranch(Buf + 4, Offset);
516}700}
517701
518void PPC64PltCallStub::addSymbols(ThunkSection &IS) {702void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
...@@ -521,6 +705,16 @@ void PPC64PltCallStub::addSymbols(ThunkSection &IS) {...@@ -521,6 +705,16 @@ void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
521 S->NeedsTocRestore = true;705 S->NeedsTocRestore = true;
522}706}
523707
708void PPC64LongBranchThunk::writeTo(uint8_t *Buf) {
709 int64_t Offset = Destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
710 writePPCLoadAndBranch(Buf, Offset);
711}
712
713void PPC64LongBranchThunk::addSymbols(ThunkSection &IS) {
714 addSymbol(Saver.save("__long_branch_" + Destination.getName()), STT_FUNC, 0,
715 IS);
716}
717
524Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}718Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
525719
526Thunk::~Thunk() = default;720Thunk::~Thunk() = default;
...@@ -528,28 +722,85 @@ Thunk::~Thunk() = default;...@@ -528,28 +722,85 @@ Thunk::~Thunk() = default;
528static Thunk *addThunkAArch64(RelType Type, Symbol &S) {722static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
529 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)723 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
530 fatal("unrecognized relocation type");724 fatal("unrecognized relocation type");
531 if (Config->Pic)725 if (Config->PicThunk)
532 return make<AArch64ADRPThunk>(S);726 return make<AArch64ADRPThunk>(S);
533 return make<AArch64ABSLongThunk>(S);727 return make<AArch64ABSLongThunk>(S);
534}728}
535729
536// Creates a thunk for Thumb-ARM interworking.730// Creates a thunk for Thumb-ARM interworking.
537static Thunk *addThunkArm(RelType Reloc, Symbol &S) {731// Arm Architectures v5 and v6 do not support Thumb2 technology. This means
538 // ARM relocations need ARM to Thumb interworking Thunks.732// - MOVT and MOVW instructions cannot be used
539 // Thumb relocations need Thumb to ARM relocations.733// - Only Thumb relocation that can generate a Thunk is a BL, this can always
540 // Use position independent Thunks if we require position independent code.734// be transformed into a BLX
735static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
541 switch (Reloc) {736 switch (Reloc) {
542 case R_ARM_PC24:737 case R_ARM_PC24:
543 case R_ARM_PLT32:738 case R_ARM_PLT32:
544 case R_ARM_JUMP24:739 case R_ARM_JUMP24:
545 case R_ARM_CALL:740 case R_ARM_CALL:
741 case R_ARM_THM_CALL:
742 if (Config->PicThunk)
743 return make<ARMV5PILongThunk>(S);
744 return make<ARMV5ABSLongThunk>(S);
745 }
746 fatal("relocation " + toString(Reloc) + " to " + toString(S) +
747 " not supported for Armv5 or Armv6 targets");
748}
749
750// Create a thunk for Thumb long branch on V6-M.
751// Arm Architecture v6-M only supports Thumb instructions. This means
752// - MOVT and MOVW instructions cannot be used.
753// - Only a limited number of instructions can access registers r8 and above
754// - No interworking support is needed (all Thumb).
755static Thunk *addThunkV6M(RelType Reloc, Symbol &S) {
756 switch (Reloc) {
757 case R_ARM_THM_JUMP19:
758 case R_ARM_THM_JUMP24:
759 case R_ARM_THM_CALL:
546 if (Config->Pic)760 if (Config->Pic)
761 return make<ThumbV6MPILongThunk>(S);
762 return make<ThumbV6MABSLongThunk>(S);
763 }
764 fatal("relocation " + toString(Reloc) + " to " + toString(S) +
765 " not supported for Armv6-M targets");
766}
767
768// Creates a thunk for Thumb-ARM interworking or branch range extension.
769static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
770 // Decide which Thunk is needed based on:
771 // Available instruction set
772 // - An Arm Thunk can only be used if Arm state is available.
773 // - A Thumb Thunk can only be used if Thumb state is available.
774 // - Can only use a Thunk if it uses instructions that the Target supports.
775 // Relocation is branch or branch and link
776 // - Branch instructions cannot change state, can only select Thunk that
777 // starts in the same state as the caller.
778 // - Branch and link relocations can change state, can select Thunks from
779 // either Arm or Thumb.
780 // Position independent Thunks if we require position independent code.
781
782 // Handle architectures that have restrictions on the instructions that they
783 // can use in Thunks. The flags below are set by reading the BuildAttributes
784 // of the input objects. InputFiles.cpp contains the mapping from ARM
785 // architecture to flag.
786 if (!Config->ARMHasMovtMovw) {
787 if (!Config->ARMJ1J2BranchEncoding)
788 return addThunkPreArmv7(Reloc, S);
789 return addThunkV6M(Reloc, S);
790 }
791
792 switch (Reloc) {
793 case R_ARM_PC24:
794 case R_ARM_PLT32:
795 case R_ARM_JUMP24:
796 case R_ARM_CALL:
797 if (Config->PicThunk)
547 return make<ARMV7PILongThunk>(S);798 return make<ARMV7PILongThunk>(S);
548 return make<ARMV7ABSLongThunk>(S);799 return make<ARMV7ABSLongThunk>(S);
549 case R_ARM_THM_JUMP19:800 case R_ARM_THM_JUMP19:
550 case R_ARM_THM_JUMP24:801 case R_ARM_THM_JUMP24:
551 case R_ARM_THM_CALL:802 case R_ARM_THM_CALL:
552 if (Config->Pic)803 if (Config->PicThunk)
553 return make<ThumbV7PILongThunk>(S);804 return make<ThumbV7PILongThunk>(S);
554 return make<ThumbV7ABSLongThunk>(S);805 return make<ThumbV7ABSLongThunk>(S);
555 }806 }
...@@ -565,9 +816,14 @@ static Thunk *addThunkMips(RelType Type, Symbol &S) {...@@ -565,9 +816,14 @@ static Thunk *addThunkMips(RelType Type, Symbol &S) {
565}816}
566817
567static Thunk *addThunkPPC64(RelType Type, Symbol &S) {818static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
568 if (Type == R_PPC64_REL24)819 assert(Type == R_PPC64_REL24 && "unexpected relocation type for thunk");
820 if (S.isInPlt())
569 return make<PPC64PltCallStub>(S);821 return make<PPC64PltCallStub>(S);
570 fatal("unexpected relocation type");822
823 if (Config->PicThunk)
824 return make<PPC64PILongBranchThunk>(S);
825
826 return make<PPC64PDLongBranchThunk>(S);
571}827}
572828
573Thunk *addThunk(RelType Type, Symbol &S) {829Thunk *addThunk(RelType Type, Symbol &S) {
deps/lld/ELF/Writer.cpp+403-282
...@@ -53,8 +53,10 @@ private:...@@ -53,8 +53,10 @@ private:
53 void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);53 void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
54 void sortSections();54 void sortSections();
55 void resolveShfLinkOrder();55 void resolveShfLinkOrder();
56 void maybeAddThunks();
56 void sortInputSections();57 void sortInputSections();
57 void finalizeSections();58 void finalizeSections();
59 void checkExecuteOnly();
58 void setReservedSymbolSections();60 void setReservedSymbolSections();
5961
60 std::vector<PhdrEntry *> createPhdrs();62 std::vector<PhdrEntry *> createPhdrs();
...@@ -77,7 +79,6 @@ private:...@@ -77,7 +79,6 @@ private:
77 void addRelIpltSymbols();79 void addRelIpltSymbols();
78 void addStartEndSymbols();80 void addStartEndSymbols();
79 void addStartStopSymbols(OutputSection *Sec);81 void addStartStopSymbols(OutputSection *Sec);
80 uint64_t getEntryAddr();
8182
82 std::vector<PhdrEntry *> Phdrs;83 std::vector<PhdrEntry *> Phdrs;
8384
...@@ -114,18 +115,16 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {...@@ -114,18 +115,16 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {
114 // for instance.115 // for instance.
115 if (Config->ZKeepTextSectionPrefix)116 if (Config->ZKeepTextSectionPrefix)
116 for (StringRef V :117 for (StringRef V :
117 {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) {118 {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})
118 if (isSectionPrefix(V, S->Name))119 if (isSectionPrefix(V, S->Name))
119 return V.drop_back();120 return V.drop_back();
120 }
121121
122 for (StringRef V :122 for (StringRef V :
123 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",123 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
124 ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",124 ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
125 ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) {125 ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
126 if (isSectionPrefix(V, S->Name))126 if (isSectionPrefix(V, S->Name))
127 return V.drop_back();127 return V.drop_back();
128 }
129128
130 // CommonSection is identified as "COMMON" in linker scripts.129 // CommonSection is identified as "COMMON" in linker scripts.
131 // By default, it should go to .bss section.130 // By default, it should go to .bss section.
...@@ -159,7 +158,7 @@ template <class ELFT> static void combineEhFrameSections() {...@@ -159,7 +158,7 @@ template <class ELFT> static void combineEhFrameSections() {
159 if (!ES || !ES->Live)158 if (!ES || !ES->Live)
160 continue;159 continue;
161160
162 InX::EhFrame->addSection<ELFT>(ES);161 In.EhFrame->addSection<ELFT>(ES);
163 S = nullptr;162 S = nullptr;
164 }163 }
165164
...@@ -173,10 +172,14 @@ static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,...@@ -173,10 +172,14 @@ static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
173 Symbol *S = Symtab->find(Name);172 Symbol *S = Symtab->find(Name);
174 if (!S || S->isDefined())173 if (!S || S->isDefined())
175 return nullptr;174 return nullptr;
176 Symbol *Sym = Symtab->addRegular(Name, StOther, STT_NOTYPE, Val,175 return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val,
177 /*Size=*/0, Binding, Sec,176 /*Size=*/0, Binding, Sec,
178 /*File=*/nullptr);177 /*File=*/nullptr);
179 return cast<Defined>(Sym);178}
179
180static Defined *addAbsolute(StringRef Name) {
181 return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL,
182 nullptr, nullptr);
180}183}
181184
182// The linker is expected to define some symbols depending on185// The linker is expected to define some symbols depending on
...@@ -188,21 +191,19 @@ void elf::addReservedSymbols() {...@@ -188,21 +191,19 @@ void elf::addReservedSymbols() {
188 // to GOT. Default offset is 0x7ff0.191 // to GOT. Default offset is 0x7ff0.
189 // See "Global Data Symbols" in Chapter 6 in the following document:192 // See "Global Data Symbols" in Chapter 6 in the following document:
190 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf193 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
191 ElfSym::MipsGp = Symtab->addAbsolute("_gp", STV_HIDDEN, STB_GLOBAL);194 ElfSym::MipsGp = addAbsolute("_gp");
192195
193 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between196 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
194 // start of function and 'gp' pointer into GOT.197 // start of function and 'gp' pointer into GOT.
195 if (Symtab->find("_gp_disp"))198 if (Symtab->find("_gp_disp"))
196 ElfSym::MipsGpDisp =199 ElfSym::MipsGpDisp = addAbsolute("_gp_disp");
197 Symtab->addAbsolute("_gp_disp", STV_HIDDEN, STB_GLOBAL);
198200
199 // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'201 // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
200 // pointer. This symbol is used in the code generated by .cpload pseudo-op202 // pointer. This symbol is used in the code generated by .cpload pseudo-op
201 // in case of using -mno-shared option.203 // in case of using -mno-shared option.
202 // https://sourceware.org/ml/binutils/2004-12/msg00094.html204 // https://sourceware.org/ml/binutils/2004-12/msg00094.html
203 if (Symtab->find("__gnu_local_gp"))205 if (Symtab->find("__gnu_local_gp"))
204 ElfSym::MipsLocalGp =206 ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");
205 Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
206 }207 }
207208
208 // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which209 // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which
...@@ -211,9 +212,20 @@ void elf::addReservedSymbols() {...@@ -211,9 +212,20 @@ void elf::addReservedSymbols() {
211 // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to212 // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to
212 // represent the TOC base which is offset by 0x8000 bytes from the start of213 // represent the TOC base which is offset by 0x8000 bytes from the start of
213 // the .got section.214 // the .got section.
214 ElfSym::GlobalOffsetTable = addOptionalRegular(215 // We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the
215 (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_",216 // correctness of some relocations depends on its value.
216 Out::ElfHeader, Target->GotBaseSymOff);217 StringRef GotTableSymName =
218 (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
219 if (Symbol *S = Symtab->find(GotTableSymName)) {
220 if (S->isDefined())
221 error(toString(S->File) + " cannot redefine linker defined symbol '" +
222 GotTableSymName + "'");
223 else
224 ElfSym::GlobalOffsetTable = Symtab->addDefined(
225 GotTableSymName, STV_HIDDEN, STT_NOTYPE, Target->GotBaseSymOff,
226 /*Size=*/0, STB_GLOBAL, Out::ElfHeader,
227 /*File=*/nullptr);
228 }
217229
218 // __ehdr_start is the location of ELF file headers. Note that we define230 // __ehdr_start is the location of ELF file headers. Note that we define
219 // this symbol unconditionally even when using a linker script, which231 // this symbol unconditionally even when using a linker script, which
...@@ -263,54 +275,52 @@ template <class ELFT> static void createSyntheticSections() {...@@ -263,54 +275,52 @@ template <class ELFT> static void createSyntheticSections() {
263275
264 auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };276 auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
265277
266 InX::DynStrTab = make<StringTableSection>(".dynstr", true);278 In.DynStrTab = make<StringTableSection>(".dynstr", true);
267 InX::Dynamic = make<DynamicSection<ELFT>>();279 In.Dynamic = make<DynamicSection<ELFT>>();
268 if (Config->AndroidPackDynRelocs) {280 if (Config->AndroidPackDynRelocs) {
269 InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(281 In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
270 Config->IsRela ? ".rela.dyn" : ".rel.dyn");282 Config->IsRela ? ".rela.dyn" : ".rel.dyn");
271 } else {283 } else {
272 InX::RelaDyn = make<RelocationSection<ELFT>>(284 In.RelaDyn = make<RelocationSection<ELFT>>(
273 Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);285 Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
274 }286 }
275 InX::ShStrTab = make<StringTableSection>(".shstrtab", false);287 In.ShStrTab = make<StringTableSection>(".shstrtab", false);
276288
277 Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);289 Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
278 Out::ProgramHeaders->Alignment = Config->Wordsize;290 Out::ProgramHeaders->Alignment = Config->Wordsize;
279291
280 if (needsInterpSection()) {292 if (needsInterpSection()) {
281 InX::Interp = createInterpSection();293 In.Interp = createInterpSection();
282 Add(InX::Interp);294 Add(In.Interp);
283 } else {
284 InX::Interp = nullptr;
285 }295 }
286296
287 if (Config->Strip != StripPolicy::All) {297 if (Config->Strip != StripPolicy::All) {
288 InX::StrTab = make<StringTableSection>(".strtab", false);298 In.StrTab = make<StringTableSection>(".strtab", false);
289 InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);299 In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
290 InX::SymTabShndx = make<SymtabShndxSection>();300 In.SymTabShndx = make<SymtabShndxSection>();
291 }301 }
292302
293 if (Config->BuildId != BuildIdKind::None) {303 if (Config->BuildId != BuildIdKind::None) {
294 InX::BuildId = make<BuildIdSection>();304 In.BuildId = make<BuildIdSection>();
295 Add(InX::BuildId);305 Add(In.BuildId);
296 }306 }
297307
298 InX::Bss = make<BssSection>(".bss", 0, 1);308 In.Bss = make<BssSection>(".bss", 0, 1);
299 Add(InX::Bss);309 Add(In.Bss);
300310
301 // If there is a SECTIONS command and a .data.rel.ro section name use name311 // If there is a SECTIONS command and a .data.rel.ro section name use name
302 // .data.rel.ro.bss so that we match in the .data.rel.ro output section.312 // .data.rel.ro.bss so that we match in the .data.rel.ro output section.
303 // This makes sure our relro is contiguous.313 // This makes sure our relro is contiguous.
304 bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");314 bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");
305 InX::BssRelRo =315 In.BssRelRo =
306 make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);316 make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
307 Add(InX::BssRelRo);317 Add(In.BssRelRo);
308318
309 // Add MIPS-specific sections.319 // Add MIPS-specific sections.
310 if (Config->EMachine == EM_MIPS) {320 if (Config->EMachine == EM_MIPS) {
311 if (!Config->Shared && Config->HasDynSymTab) {321 if (!Config->Shared && Config->HasDynSymTab) {
312 InX::MipsRldMap = make<MipsRldMapSection>();322 In.MipsRldMap = make<MipsRldMapSection>();
313 Add(InX::MipsRldMap);323 Add(In.MipsRldMap);
314 }324 }
315 if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())325 if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
316 Add(Sec);326 Add(Sec);
...@@ -321,65 +331,70 @@ template <class ELFT> static void createSyntheticSections() {...@@ -321,65 +331,70 @@ template <class ELFT> static void createSyntheticSections() {
321 }331 }
322332
323 if (Config->HasDynSymTab) {333 if (Config->HasDynSymTab) {
324 InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);334 In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
325 Add(InX::DynSymTab);335 Add(In.DynSymTab);
326336
327 In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();337 InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
328 Add(In<ELFT>::VerSym);338 Add(InX<ELFT>::VerSym);
329339
330 if (!Config->VersionDefinitions.empty()) {340 if (!Config->VersionDefinitions.empty()) {
331 In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();341 In.VerDef = make<VersionDefinitionSection>();
332 Add(In<ELFT>::VerDef);342 Add(In.VerDef);
333 }343 }
334344
335 In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();345 InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
336 Add(In<ELFT>::VerNeed);346 Add(InX<ELFT>::VerNeed);
337347
338 if (Config->GnuHash) {348 if (Config->GnuHash) {
339 InX::GnuHashTab = make<GnuHashTableSection>();349 In.GnuHashTab = make<GnuHashTableSection>();
340 Add(InX::GnuHashTab);350 Add(In.GnuHashTab);
341 }351 }
342352
343 if (Config->SysvHash) {353 if (Config->SysvHash) {
344 InX::HashTab = make<HashTableSection>();354 In.HashTab = make<HashTableSection>();
345 Add(InX::HashTab);355 Add(In.HashTab);
346 }356 }
347357
348 Add(InX::Dynamic);358 Add(In.Dynamic);
349 Add(InX::DynStrTab);359 Add(In.DynStrTab);
350 Add(InX::RelaDyn);360 Add(In.RelaDyn);
351 }361 }
352362
353 if (Config->RelrPackDynRelocs) {363 if (Config->RelrPackDynRelocs) {
354 InX::RelrDyn = make<RelrSection<ELFT>>();364 In.RelrDyn = make<RelrSection<ELFT>>();
355 Add(InX::RelrDyn);365 Add(In.RelrDyn);
356 }366 }
357367
358 // Add .got. MIPS' .got is so different from the other archs,368 // Add .got. MIPS' .got is so different from the other archs,
359 // it has its own class.369 // it has its own class.
360 if (Config->EMachine == EM_MIPS) {370 if (Config->EMachine == EM_MIPS) {
361 InX::MipsGot = make<MipsGotSection>();371 In.MipsGot = make<MipsGotSection>();
362 Add(InX::MipsGot);372 Add(In.MipsGot);
363 } else {373 } else {
364 InX::Got = make<GotSection>();374 In.Got = make<GotSection>();
365 Add(InX::Got);375 Add(In.Got);
366 }376 }
367377
368 InX::GotPlt = make<GotPltSection>();378 if (Config->EMachine == EM_PPC64) {
369 Add(InX::GotPlt);379 In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>();
370 InX::IgotPlt = make<IgotPltSection>();380 Add(In.PPC64LongBranchTarget);
371 Add(InX::IgotPlt);381 }
382
383 In.GotPlt = make<GotPltSection>();
384 Add(In.GotPlt);
385 In.IgotPlt = make<IgotPltSection>();
386 Add(In.IgotPlt);
372387
373 if (Config->GdbIndex) {388 if (Config->GdbIndex) {
374 InX::GdbIndex = GdbIndexSection::create<ELFT>();389 In.GdbIndex = GdbIndexSection::create<ELFT>();
375 Add(InX::GdbIndex);390 Add(In.GdbIndex);
376 }391 }
377392
378 // We always need to add rel[a].plt to output if it has entries.393 // We always need to add rel[a].plt to output if it has entries.
379 // Even for static linking it can contain R_[*]_IRELATIVE relocations.394 // Even for static linking it can contain R_[*]_IRELATIVE relocations.
380 InX::RelaPlt = make<RelocationSection<ELFT>>(395 In.RelaPlt = make<RelocationSection<ELFT>>(
381 Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);396 Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
382 Add(InX::RelaPlt);397 Add(In.RelaPlt);
383398
384 // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure399 // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
385 // that the IRelative relocations are processed last by the dynamic loader.400 // that the IRelative relocations are processed last by the dynamic loader.
...@@ -387,34 +402,42 @@ template <class ELFT> static void createSyntheticSections() {...@@ -387,34 +402,42 @@ template <class ELFT> static void createSyntheticSections() {
387 // packing is enabled because that would cause a section type mismatch.402 // packing is enabled because that would cause a section type mismatch.
388 // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,403 // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
389 // we can get the desired behaviour by placing the iplt section in .rel.plt.404 // we can get the desired behaviour by placing the iplt section in .rel.plt.
390 InX::RelaIplt = make<RelocationSection<ELFT>>(405 In.RelaIplt = make<RelocationSection<ELFT>>(
391 (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)406 (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
392 ? ".rel.dyn"407 ? ".rel.dyn"
393 : InX::RelaPlt->Name,408 : In.RelaPlt->Name,
394 false /*Sort*/);409 false /*Sort*/);
395 Add(InX::RelaIplt);410 Add(In.RelaIplt);
396411
397 InX::Plt = make<PltSection>(false);412 In.Plt = make<PltSection>(false);
398 Add(InX::Plt);413 Add(In.Plt);
399 InX::Iplt = make<PltSection>(true);414 In.Iplt = make<PltSection>(true);
400 Add(InX::Iplt);415 Add(In.Iplt);
416
417 // .note.GNU-stack is always added when we are creating a re-linkable
418 // object file. Other linkers are using the presence of this marker
419 // section to control the executable-ness of the stack area, but that
420 // is irrelevant these days. Stack area should always be non-executable
421 // by default. So we emit this section unconditionally.
422 if (Config->Relocatable)
423 Add(make<GnuStackSection>());
401424
402 if (!Config->Relocatable) {425 if (!Config->Relocatable) {
403 if (Config->EhFrameHdr) {426 if (Config->EhFrameHdr) {
404 InX::EhFrameHdr = make<EhFrameHeader>();427 In.EhFrameHdr = make<EhFrameHeader>();
405 Add(InX::EhFrameHdr);428 Add(In.EhFrameHdr);
406 }429 }
407 InX::EhFrame = make<EhFrameSection>();430 In.EhFrame = make<EhFrameSection>();
408 Add(InX::EhFrame);431 Add(In.EhFrame);
409 }432 }
410433
411 if (InX::SymTab)434 if (In.SymTab)
412 Add(InX::SymTab);435 Add(In.SymTab);
413 if (InX::SymTabShndx)436 if (In.SymTabShndx)
414 Add(InX::SymTabShndx);437 Add(In.SymTabShndx);
415 Add(InX::ShStrTab);438 Add(In.ShStrTab);
416 if (InX::StrTab)439 if (In.StrTab)
417 Add(InX::StrTab);440 Add(In.StrTab);
418441
419 if (Config->EMachine == EM_ARM && !Config->Relocatable)442 if (Config->EMachine == EM_ARM && !Config->Relocatable)
420 // Add a sentinel to terminate .ARM.exidx. It helps an unwinder443 // Add a sentinel to terminate .ARM.exidx. It helps an unwinder
...@@ -451,6 +474,7 @@ template <class ELFT> void Writer<ELFT>::run() {...@@ -451,6 +474,7 @@ template <class ELFT> void Writer<ELFT>::run() {
451 // to the string table, and add entries to .got and .plt.474 // to the string table, and add entries to .got and .plt.
452 // finalizeSections does that.475 // finalizeSections does that.
453 finalizeSections();476 finalizeSections();
477 checkExecuteOnly();
454 if (errorCount())478 if (errorCount())
455 return;479 return;
456480
...@@ -476,10 +500,9 @@ template <class ELFT> void Writer<ELFT>::run() {...@@ -476,10 +500,9 @@ template <class ELFT> void Writer<ELFT>::run() {
476500
477 setPhdrs();501 setPhdrs();
478502
479 if (Config->Relocatable) {503 if (Config->Relocatable)
480 for (OutputSection *Sec : OutputSections)504 for (OutputSection *Sec : OutputSections)
481 Sec->Addr = 0;505 Sec->Addr = 0;
482 }
483506
484 if (Config->CheckSections)507 if (Config->CheckSections)
485 checkSections();508 checkSections();
...@@ -548,9 +571,11 @@ static bool includeInSymtab(const Symbol &B) {...@@ -548,9 +571,11 @@ static bool includeInSymtab(const Symbol &B) {
548 if (!Sec)571 if (!Sec)
549 return true;572 return true;
550 Sec = Sec->Repl;573 Sec = Sec->Repl;
574
551 // Exclude symbols pointing to garbage-collected sections.575 // Exclude symbols pointing to garbage-collected sections.
552 if (isa<InputSectionBase>(Sec) && !Sec->Live)576 if (isa<InputSectionBase>(Sec) && !Sec->Live)
553 return false;577 return false;
578
554 if (auto *S = dyn_cast<MergeInputSection>(Sec))579 if (auto *S = dyn_cast<MergeInputSection>(Sec))
555 if (!S->getSectionPiece(D->Value)->Live)580 if (!S->getSectionPiece(D->Value)->Live)
556 return false;581 return false;
...@@ -562,7 +587,7 @@ static bool includeInSymtab(const Symbol &B) {...@@ -562,7 +587,7 @@ static bool includeInSymtab(const Symbol &B) {
562// Local symbols are not in the linker's symbol table. This function scans587// Local symbols are not in the linker's symbol table. This function scans
563// each object file's symbol table to copy local symbols to the output.588// each object file's symbol table to copy local symbols to the output.
564template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {589template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
565 if (!InX::SymTab)590 if (!In.SymTab)
566 return;591 return;
567 for (InputFile *File : ObjectFiles) {592 for (InputFile *File : ObjectFiles) {
568 ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);593 ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
...@@ -581,16 +606,16 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {...@@ -581,16 +606,16 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
581 SectionBase *Sec = DR->Section;606 SectionBase *Sec = DR->Section;
582 if (!shouldKeepInSymtab(Sec, B->getName(), *B))607 if (!shouldKeepInSymtab(Sec, B->getName(), *B))
583 continue;608 continue;
584 InX::SymTab->addSymbol(B);609 In.SymTab->addSymbol(B);
585 }610 }
586 }611 }
587}612}
588613
614// Create a section symbol for each output section so that we can represent
615// relocations that point to the section. If we know that no relocation is
616// referring to a section (that happens if the section is a synthetic one), we
617// don't create a section symbol for that section.
589template <class ELFT> void Writer<ELFT>::addSectionSymbols() {618template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
590 // Create a section symbol for each output section so that we can represent
591 // relocations that point to the section. If we know that no relocation is
592 // referring to a section (that happens if the section is a synthetic one), we
593 // don't create a section symbol for that section.
594 for (BaseCommand *Base : Script->SectionCommands) {619 for (BaseCommand *Base : Script->SectionCommands) {
595 auto *Sec = dyn_cast<OutputSection>(Base);620 auto *Sec = dyn_cast<OutputSection>(Base);
596 if (!Sec)621 if (!Sec)
...@@ -617,7 +642,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {...@@ -617,7 +642,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
617 auto *Sym =642 auto *Sym =
618 make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,643 make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
619 /*Value=*/0, /*Size=*/0, IS);644 /*Value=*/0, /*Size=*/0, IS);
620 InX::SymTab->addSymbol(Sym);645 In.SymTab->addSymbol(Sym);
621 }646 }
622}647}
623648
...@@ -662,9 +687,14 @@ static bool isRelroSection(const OutputSection *Sec) {...@@ -662,9 +687,14 @@ static bool isRelroSection(const OutputSection *Sec) {
662 // .got contains pointers to external symbols. They are resolved by687 // .got contains pointers to external symbols. They are resolved by
663 // the dynamic linker when a module is loaded into memory, and after688 // the dynamic linker when a module is loaded into memory, and after
664 // that they are not expected to change. So, it can be in RELRO.689 // that they are not expected to change. So, it can be in RELRO.
665 if (InX::Got && Sec == InX::Got->getParent())690 if (In.Got && Sec == In.Got->getParent())
666 return true;691 return true;
667692
693 // .toc is a GOT-ish section for PowerPC64. Their contents are accessed
694 // through r2 register, which is reserved for that purpose. Since r2 is used
695 // for accessing .got as well, .got and .toc need to be close enough in the
696 // virtual address space. Usually, .toc comes just after .got. Since we place
697 // .got into RELRO, .toc needs to be placed into RELRO too.
668 if (Sec->Name.equals(".toc"))698 if (Sec->Name.equals(".toc"))
669 return true;699 return true;
670700
...@@ -672,13 +702,13 @@ static bool isRelroSection(const OutputSection *Sec) {...@@ -672,13 +702,13 @@ static bool isRelroSection(const OutputSection *Sec) {
672 // by default resolved lazily, so we usually cannot put it into RELRO.702 // by default resolved lazily, so we usually cannot put it into RELRO.
673 // However, if "-z now" is given, the lazy symbol resolution is703 // However, if "-z now" is given, the lazy symbol resolution is
674 // disabled, which enables us to put it into RELRO.704 // disabled, which enables us to put it into RELRO.
675 if (Sec == InX::GotPlt->getParent())705 if (Sec == In.GotPlt->getParent())
676 return Config->ZNow;706 return Config->ZNow;
677707
678 // .dynamic section contains data for the dynamic linker, and708 // .dynamic section contains data for the dynamic linker, and
679 // there's no need to write to it at runtime, so it's better to put709 // there's no need to write to it at runtime, so it's better to put
680 // it into RELRO.710 // it into RELRO.
681 if (Sec == InX::Dynamic->getParent())711 if (Sec == In.Dynamic->getParent())
682 return true;712 return true;
683713
684 // Sections with some special names are put into RELRO. This is a714 // Sections with some special names are put into RELRO. This is a
...@@ -700,17 +730,17 @@ static bool isRelroSection(const OutputSection *Sec) {...@@ -700,17 +730,17 @@ static bool isRelroSection(const OutputSection *Sec) {
700// * It is easy two see how similar two ranks are (see getRankProximity).730// * It is easy two see how similar two ranks are (see getRankProximity).
701enum RankFlags {731enum RankFlags {
702 RF_NOT_ADDR_SET = 1 << 18,732 RF_NOT_ADDR_SET = 1 << 18,
703 RF_NOT_INTERP = 1 << 17,733 RF_NOT_ALLOC = 1 << 17,
704 RF_NOT_ALLOC = 1 << 16,734 RF_NOT_INTERP = 1 << 16,
705 RF_WRITE = 1 << 15,735 RF_NOT_NOTE = 1 << 15,
706 RF_EXEC_WRITE = 1 << 14,736 RF_WRITE = 1 << 14,
707 RF_EXEC = 1 << 13,737 RF_EXEC_WRITE = 1 << 13,
708 RF_RODATA = 1 << 12,738 RF_EXEC = 1 << 12,
709 RF_NON_TLS_BSS = 1 << 11,739 RF_RODATA = 1 << 11,
710 RF_NON_TLS_BSS_RO = 1 << 10,740 RF_NON_TLS_BSS = 1 << 10,
711 RF_NOT_TLS = 1 << 9,741 RF_NON_TLS_BSS_RO = 1 << 9,
712 RF_BSS = 1 << 8,742 RF_NOT_TLS = 1 << 8,
713 RF_NOTE = 1 << 7,743 RF_BSS = 1 << 7,
714 RF_PPC_NOT_TOCBSS = 1 << 6,744 RF_PPC_NOT_TOCBSS = 1 << 6,
715 RF_PPC_TOCL = 1 << 5,745 RF_PPC_TOCL = 1 << 5,
716 RF_PPC_TOC = 1 << 4,746 RF_PPC_TOC = 1 << 4,
...@@ -729,16 +759,24 @@ static unsigned getSectionRank(const OutputSection *Sec) {...@@ -729,16 +759,24 @@ static unsigned getSectionRank(const OutputSection *Sec) {
729 return Rank;759 return Rank;
730 Rank |= RF_NOT_ADDR_SET;760 Rank |= RF_NOT_ADDR_SET;
731761
762 // Allocatable sections go first to reduce the total PT_LOAD size and
763 // so debug info doesn't change addresses in actual code.
764 if (!(Sec->Flags & SHF_ALLOC))
765 return Rank | RF_NOT_ALLOC;
766
732 // Put .interp first because some loaders want to see that section767 // Put .interp first because some loaders want to see that section
733 // on the first page of the executable file when loaded into memory.768 // on the first page of the executable file when loaded into memory.
734 if (Sec->Name == ".interp")769 if (Sec->Name == ".interp")
735 return Rank;770 return Rank;
736 Rank |= RF_NOT_INTERP;771 Rank |= RF_NOT_INTERP;
737772
738 // Allocatable sections go first to reduce the total PT_LOAD size and773 // Put .note sections (which make up one PT_NOTE) at the beginning so that
739 // so debug info doesn't change addresses in actual code.774 // they are likely to be included in a core file even if core file size is
740 if (!(Sec->Flags & SHF_ALLOC))775 // limited. In particular, we want a .note.gnu.build-id and a .note.tag to be
741 return Rank | RF_NOT_ALLOC;776 // included in a core to match core files with executables.
777 if (Sec->Type == SHT_NOTE)
778 return Rank;
779 Rank |= RF_NOT_NOTE;
742780
743 // Sort sections based on their access permission in the following781 // Sort sections based on their access permission in the following
744 // order: R, RX, RWX, RW. This order is based on the following782 // order: R, RX, RWX, RW. This order is based on the following
...@@ -802,12 +840,6 @@ static unsigned getSectionRank(const OutputSection *Sec) {...@@ -802,12 +840,6 @@ static unsigned getSectionRank(const OutputSection *Sec) {
802 if (IsNoBits)840 if (IsNoBits)
803 Rank |= RF_BSS;841 Rank |= RF_BSS;
804842
805 // We create a NOTE segment for contiguous .note sections, so make
806 // them contigous if there are more than one .note section with the
807 // same attributes.
808 if (Sec->Type == SHT_NOTE)
809 Rank |= RF_NOTE;
810
811 // Some architectures have additional ordering restrictions for sections843 // Some architectures have additional ordering restrictions for sections
812 // within the same PT_LOAD.844 // within the same PT_LOAD.
813 if (Config->EMachine == EM_PPC64) {845 if (Config->EMachine == EM_PPC64) {
...@@ -850,8 +882,10 @@ static unsigned getSectionRank(const OutputSection *Sec) {...@@ -850,8 +882,10 @@ static unsigned getSectionRank(const OutputSection *Sec) {
850static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {882static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
851 const OutputSection *A = cast<OutputSection>(ACmd);883 const OutputSection *A = cast<OutputSection>(ACmd);
852 const OutputSection *B = cast<OutputSection>(BCmd);884 const OutputSection *B = cast<OutputSection>(BCmd);
885
853 if (A->SortRank != B->SortRank)886 if (A->SortRank != B->SortRank)
854 return A->SortRank < B->SortRank;887 return A->SortRank < B->SortRank;
888
855 if (!(A->SortRank & RF_NOT_ADDR_SET))889 if (!(A->SortRank & RF_NOT_ADDR_SET))
856 return Config->SectionStartMap.lookup(A->Name) <890 return Config->SectionStartMap.lookup(A->Name) <
857 Config->SectionStartMap.lookup(B->Name);891 Config->SectionStartMap.lookup(B->Name);
...@@ -874,14 +908,20 @@ void PhdrEntry::add(OutputSection *Sec) {...@@ -874,14 +908,20 @@ void PhdrEntry::add(OutputSection *Sec) {
874// need these symbols, since IRELATIVE relocs are resolved through GOT908// need these symbols, since IRELATIVE relocs are resolved through GOT
875// and PLT. For details, see http://www.airs.com/blog/archives/403.909// and PLT. For details, see http://www.airs.com/blog/archives/403.
876template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {910template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
877 if (needsInterpSection())911 if (Config->Relocatable || needsInterpSection())
878 return;912 return;
879 StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
880 addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
881913
882 S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";914 // By default, __rela_iplt_{start,end} belong to a dummy section 0
883 ElfSym::RelaIpltEnd =915 // because .rela.plt might be empty and thus removed from output.
884 addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);916 // We'll override Out::ElfHeader with In.RelaIplt later when we are
917 // sure that .rela.plt exists in output.
918 ElfSym::RelaIpltStart = addOptionalRegular(
919 Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
920 Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
921
922 ElfSym::RelaIpltEnd = addOptionalRegular(
923 Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
924 Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
885}925}
886926
887template <class ELFT>927template <class ELFT>
...@@ -895,7 +935,7 @@ void Writer<ELFT>::forEachRelSec(...@@ -895,7 +935,7 @@ void Writer<ELFT>::forEachRelSec(
895 for (InputSectionBase *IS : InputSections)935 for (InputSectionBase *IS : InputSections)
896 if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))936 if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
897 Fn(*IS);937 Fn(*IS);
898 for (EhInputSection *ES : InX::EhFrame->Sections)938 for (EhInputSection *ES : In.EhFrame->Sections)
899 Fn(*ES);939 Fn(*ES);
900}940}
901941
...@@ -908,15 +948,19 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {...@@ -908,15 +948,19 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
908 if (ElfSym::GlobalOffsetTable) {948 if (ElfSym::GlobalOffsetTable) {
909 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually949 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
910 // to the start of the .got or .got.plt section.950 // to the start of the .got or .got.plt section.
911 InputSection *GotSection = InX::GotPlt;951 InputSection *GotSection = In.GotPlt;
912 if (!Target->GotBaseSymInGotPlt)952 if (!Target->GotBaseSymInGotPlt)
913 GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)953 GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
914 : cast<InputSection>(InX::Got);954 : cast<InputSection>(In.Got);
915 ElfSym::GlobalOffsetTable->Section = GotSection;955 ElfSym::GlobalOffsetTable->Section = GotSection;
916 }956 }
917957
918 if (ElfSym::RelaIpltEnd)958 // .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
919 ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize();959 if (ElfSym::RelaIpltStart && !In.RelaIplt->empty()) {
960 ElfSym::RelaIpltStart->Section = In.RelaIplt;
961 ElfSym::RelaIpltEnd->Section = In.RelaIplt;
962 ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
963 }
920964
921 PhdrEntry *Last = nullptr;965 PhdrEntry *Last = nullptr;
922 PhdrEntry *LastRO = nullptr;966 PhdrEntry *LastRO = nullptr;
...@@ -1088,7 +1132,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {...@@ -1088,7 +1132,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
1088 SymbolOrderEntry &Ent = It->second;1132 SymbolOrderEntry &Ent = It->second;
1089 Ent.Present = true;1133 Ent.Present = true;
10901134
1091 warnUnorderableSymbol(&Sym);1135 maybeWarnUnorderableSymbol(&Sym);
10921136
1093 if (auto *D = dyn_cast<Defined>(&Sym)) {1137 if (auto *D = dyn_cast<Defined>(&Sym)) {
1094 if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {1138 if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
...@@ -1097,6 +1141,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {...@@ -1097,6 +1141,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
1097 }1141 }
1098 }1142 }
1099 };1143 };
1144
1100 // We want both global and local symbols. We get the global ones from the1145 // We want both global and local symbols. We get the global ones from the
1101 // symbol table and iterate the object files for the local ones.1146 // symbol table and iterate the object files for the local ones.
1102 for (Symbol *Sym : Symtab->getSymbols())1147 for (Symbol *Sym : Symtab->getSymbols())
...@@ -1132,11 +1177,10 @@ sortISDBySectionOrder(InputSectionDescription *ISD,...@@ -1132,11 +1177,10 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
1132 }1177 }
1133 OrderedSections.push_back({IS, I->second});1178 OrderedSections.push_back({IS, I->second});
1134 }1179 }
1135 llvm::sort(1180 llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A,
1136 OrderedSections.begin(), OrderedSections.end(),1181 std::pair<InputSection *, int> B) {
1137 [&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) {1182 return A.second < B.second;
1138 return A.second < B.second;1183 });
1139 });
11401184
1141 // Find an insertion point for the ordered section list in the unordered1185 // Find an insertion point for the ordered section list in the unordered
1142 // section list. On targets with limited-range branches, this is the mid-point1186 // section list. On targets with limited-range branches, this is the mid-point
...@@ -1166,7 +1210,7 @@ sortISDBySectionOrder(InputSectionDescription *ISD,...@@ -1166,7 +1210,7 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
1166 // we effectively double the amount of code that could potentially call into1210 // we effectively double the amount of code that could potentially call into
1167 // the hot code without a thunk.1211 // the hot code without a thunk.
1168 size_t InsPt = 0;1212 size_t InsPt = 0;
1169 if (Target->ThunkSectionSpacing && !OrderedSections.empty()) {1213 if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
1170 uint64_t UnorderedPos = 0;1214 uint64_t UnorderedPos = 0;
1171 for (; InsPt != UnorderedSections.size(); ++InsPt) {1215 for (; InsPt != UnorderedSections.size(); ++InsPt) {
1172 UnorderedPos += UnorderedSections[InsPt]->getSize();1216 UnorderedPos += UnorderedSections[InsPt]->getSize();
...@@ -1342,10 +1386,12 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {...@@ -1342,10 +1386,12 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {
1342 if (A->kind() == InputSectionBase::Synthetic ||1386 if (A->kind() == InputSectionBase::Synthetic ||
1343 B->kind() == InputSectionBase::Synthetic)1387 B->kind() == InputSectionBase::Synthetic)
1344 return A->kind() != InputSectionBase::Synthetic;1388 return A->kind() != InputSectionBase::Synthetic;
1389
1345 InputSection *LA = A->getLinkOrderDep();1390 InputSection *LA = A->getLinkOrderDep();
1346 InputSection *LB = B->getLinkOrderDep();1391 InputSection *LB = B->getLinkOrderDep();
1347 OutputSection *AOut = LA->getParent();1392 OutputSection *AOut = LA->getParent();
1348 OutputSection *BOut = LB->getParent();1393 OutputSection *BOut = LB->getParent();
1394
1349 if (AOut != BOut)1395 if (AOut != BOut)
1350 return AOut->SectionIndex < BOut->SectionIndex;1396 return AOut->SectionIndex < BOut->SectionIndex;
1351 return LA->OutSecOff < LB->OutSecOff;1397 return LA->OutSecOff < LB->OutSecOff;
...@@ -1392,6 +1438,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {...@@ -1392,6 +1438,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
1392 for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())1438 for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())
1393 if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)1439 if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
1394 return false;1440 return false;
1441
1395 // All table entries in this .ARM.exidx Section can be merged into the1442 // All table entries in this .ARM.exidx Section can be merged into the
1396 // previous Section.1443 // previous Section.
1397 return true;1444 return true;
...@@ -1423,18 +1470,19 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {...@@ -1423,18 +1470,19 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
1423 assert(Sections.size() >= 2 &&1470 assert(Sections.size() >= 2 &&
1424 "We should create a sentinel section only if there are "1471 "We should create a sentinel section only if there are "
1425 "alive regular exidx sections.");1472 "alive regular exidx sections.");
1473
1426 // The last executable section is required to fill the sentinel.1474 // The last executable section is required to fill the sentinel.
1427 // Remember it here so that we don't have to find it again.1475 // Remember it here so that we don't have to find it again.
1428 Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();1476 Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();
1429 }1477 }
14301478
1479 // The EHABI for the Arm Architecture permits consecutive identical
1480 // table entries to be merged. We use a simple implementation that
1481 // removes a .ARM.exidx Input Section if it can be merged into the
1482 // previous one. This does not require any rewriting of InputSection
1483 // contents but misses opportunities for fine grained deduplication
1484 // where only a subset of the InputSection contents can be merged.
1431 if (Config->MergeArmExidx) {1485 if (Config->MergeArmExidx) {
1432 // The EHABI for the Arm Architecture permits consecutive identical
1433 // table entries to be merged. We use a simple implementation that
1434 // removes a .ARM.exidx Input Section if it can be merged into the
1435 // previous one. This does not require any rewriting of InputSection
1436 // contents but misses opportunities for fine grained deduplication
1437 // where only a subset of the InputSection contents can be merged.
1438 size_t Prev = 0;1486 size_t Prev = 0;
1439 // The last one is a sentinel entry which should not be removed.1487 // The last one is a sentinel entry which should not be removed.
1440 for (size_t I = 1; I < Sections.size() - 1; ++I) {1488 for (size_t I = 1; I < Sections.size() - 1; ++I) {
...@@ -1456,11 +1504,49 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {...@@ -1456,11 +1504,49 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
1456 }1504 }
1457}1505}
14581506
1459static void applySynthetic(const std::vector<SyntheticSection *> &Sections,1507// For most RISC ISAs, we need to generate content that depends on the address
1460 llvm::function_ref<void(SyntheticSection *)> Fn) {1508// of InputSections. For example some architectures such as AArch64 use small
1461 for (SyntheticSection *SS : Sections)1509// displacements for jump instructions that is the linker's responsibility for
1462 if (SS && SS->getParent() && !SS->empty())1510// creating range extension thunks for. As the generation of the content may
1463 Fn(SS);1511// also alter InputSection addresses we must converge to a fixed point.
1512template <class ELFT> void Writer<ELFT>::maybeAddThunks() {
1513 if (!Target->NeedsThunks && !Config->AndroidPackDynRelocs &&
1514 !Config->RelrPackDynRelocs)
1515 return;
1516
1517 ThunkCreator TC;
1518 AArch64Err843419Patcher A64P;
1519
1520 for (;;) {
1521 bool Changed = false;
1522
1523 Script->assignAddresses();
1524
1525 if (Target->NeedsThunks)
1526 Changed |= TC.createThunks(OutputSections);
1527
1528 if (Config->FixCortexA53Errata843419) {
1529 if (Changed)
1530 Script->assignAddresses();
1531 Changed |= A64P.createFixes();
1532 }
1533
1534 if (In.MipsGot)
1535 In.MipsGot->updateAllocSize();
1536
1537 Changed |= In.RelaDyn->updateAllocSize();
1538
1539 if (In.RelrDyn)
1540 Changed |= In.RelrDyn->updateAllocSize();
1541
1542 if (!Changed)
1543 return;
1544 }
1545}
1546
1547static void finalizeSynthetic(SyntheticSection *Sec) {
1548 if (Sec && !Sec->empty() && Sec->getParent())
1549 Sec->finalizeContents();
1464}1550}
14651551
1466// In order to allow users to manipulate linker-synthesized sections,1552// In order to allow users to manipulate linker-synthesized sections,
...@@ -1500,6 +1586,7 @@ static void removeUnusedSyntheticSections() {...@@ -1500,6 +1586,7 @@ static void removeUnusedSyntheticSections() {
1500// with the same name defined in other ELF executable or DSO.1586// with the same name defined in other ELF executable or DSO.
1501static bool computeIsPreemptible(const Symbol &B) {1587static bool computeIsPreemptible(const Symbol &B) {
1502 assert(!B.isLocal());1588 assert(!B.isLocal());
1589
1503 // Only symbols that appear in dynsym can be preempted.1590 // Only symbols that appear in dynsym can be preempted.
1504 if (!B.includeInDynsym())1591 if (!B.includeInDynsym())
1505 return false;1592 return false;
...@@ -1528,7 +1615,6 @@ static bool computeIsPreemptible(const Symbol &B) {...@@ -1528,7 +1615,6 @@ static bool computeIsPreemptible(const Symbol &B) {
15281615
1529// Create output section objects and add them to OutputSections.1616// Create output section objects and add them to OutputSections.
1530template <class ELFT> void Writer<ELFT>::finalizeSections() {1617template <class ELFT> void Writer<ELFT>::finalizeSections() {
1531 Out::DebugInfo = findSection(".debug_info");
1532 Out::PreinitArray = findSection(".preinit_array");1618 Out::PreinitArray = findSection(".preinit_array");
1533 Out::InitArray = findSection(".init_array");1619 Out::InitArray = findSection(".init_array");
1534 Out::FiniArray = findSection(".fini_array");1620 Out::FiniArray = findSection(".fini_array");
...@@ -1547,46 +1633,51 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1547,46 +1633,51 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1547 // It should be okay as no one seems to care about the type.1633 // It should be okay as no one seems to care about the type.
1548 // Even the author of gold doesn't remember why gold behaves that way.1634 // Even the author of gold doesn't remember why gold behaves that way.
1549 // https://sourceware.org/ml/binutils/2002-03/msg00360.html1635 // https://sourceware.org/ml/binutils/2002-03/msg00360.html
1550 if (InX::DynSymTab)1636 if (In.Dynamic->Parent)
1551 Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,1637 Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
1552 /*Size=*/0, STB_WEAK, InX::Dynamic,1638 /*Size=*/0, STB_WEAK, In.Dynamic,
1553 /*File=*/nullptr);1639 /*File=*/nullptr);
15541640
1555 // Define __rel[a]_iplt_{start,end} symbols if needed.1641 // Define __rel[a]_iplt_{start,end} symbols if needed.
1556 addRelIpltSymbols();1642 addRelIpltSymbols();
15571643
1644 // RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined.
1645 if (Config->EMachine == EM_RISCV)
1646 if (!dyn_cast_or_null<Defined>(Symtab->find("__global_pointer$")))
1647 addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800);
1648
1558 // This responsible for splitting up .eh_frame section into1649 // This responsible for splitting up .eh_frame section into
1559 // pieces. The relocation scan uses those pieces, so this has to be1650 // pieces. The relocation scan uses those pieces, so this has to be
1560 // earlier.1651 // earlier.
1561 applySynthetic({InX::EhFrame},1652 finalizeSynthetic(In.EhFrame);
1562 [](SyntheticSection *SS) { SS->finalizeContents(); });
15631653
1564 for (Symbol *S : Symtab->getSymbols())1654 for (Symbol *S : Symtab->getSymbols())
1565 S->IsPreemptible |= computeIsPreemptible(*S);1655 if (!S->IsPreemptible)
1656 S->IsPreemptible = computeIsPreemptible(*S);
15661657
1567 // Scan relocations. This must be done after every symbol is declared so that1658 // Scan relocations. This must be done after every symbol is declared so that
1568 // we can correctly decide if a dynamic relocation is needed.1659 // we can correctly decide if a dynamic relocation is needed.
1569 if (!Config->Relocatable)1660 if (!Config->Relocatable)
1570 forEachRelSec(scanRelocations<ELFT>);1661 forEachRelSec(scanRelocations<ELFT>);
15711662
1572 if (InX::Plt && !InX::Plt->empty())1663 if (In.Plt && !In.Plt->empty())
1573 InX::Plt->addSymbols();1664 In.Plt->addSymbols();
1574 if (InX::Iplt && !InX::Iplt->empty())1665 if (In.Iplt && !In.Iplt->empty())
1575 InX::Iplt->addSymbols();1666 In.Iplt->addSymbols();
15761667
1577 // Now that we have defined all possible global symbols including linker-1668 // Now that we have defined all possible global symbols including linker-
1578 // synthesized ones. Visit all symbols to give the finishing touches.1669 // synthesized ones. Visit all symbols to give the finishing touches.
1579 for (Symbol *Sym : Symtab->getSymbols()) {1670 for (Symbol *Sym : Symtab->getSymbols()) {
1580 if (!includeInSymtab(*Sym))1671 if (!includeInSymtab(*Sym))
1581 continue;1672 continue;
1582 if (InX::SymTab)1673 if (In.SymTab)
1583 InX::SymTab->addSymbol(Sym);1674 In.SymTab->addSymbol(Sym);
15841675
1585 if (InX::DynSymTab && Sym->includeInDynsym()) {1676 if (Sym->includeInDynsym()) {
1586 InX::DynSymTab->addSymbol(Sym);1677 In.DynSymTab->addSymbol(Sym);
1587 if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))1678 if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
1588 if (File->IsNeeded && !Sym->isUndefined())1679 if (File->IsNeeded && !Sym->isUndefined())
1589 In<ELFT>::VerNeed->addSymbol(Sym);1680 InX<ELFT>::VerNeed->addSymbol(Sym);
1590 }1681 }
1591 }1682 }
15921683
...@@ -1594,8 +1685,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1594,8 +1685,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1594 if (errorCount())1685 if (errorCount())
1595 return;1686 return;
15961687
1597 if (InX::MipsGot)1688 if (In.MipsGot)
1598 InX::MipsGot->build<ELFT>();1689 In.MipsGot->build<ELFT>();
15991690
1600 removeUnusedSyntheticSections();1691 removeUnusedSyntheticSections();
16011692
...@@ -1607,15 +1698,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1607,15 +1698,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1607 if (auto *Sec = dyn_cast<OutputSection>(Base))1698 if (auto *Sec = dyn_cast<OutputSection>(Base))
1608 OutputSections.push_back(Sec);1699 OutputSections.push_back(Sec);
16091700
1610 // Ensure data sections are not mixed with executable sections when
1611 // -execute-only is used.
1612 if (Config->ExecuteOnly)
1613 for (OutputSection *OS : OutputSections)
1614 if (OS->Flags & SHF_EXECINSTR)
1615 for (InputSection *IS : getInputSections(OS))
1616 if (!(IS->Flags & SHF_EXECINSTR))
1617 error("-execute-only does not support intermingling data and code");
1618
1619 // Prefer command line supplied address over other constraints.1701 // Prefer command line supplied address over other constraints.
1620 for (OutputSection *Sec : OutputSections) {1702 for (OutputSection *Sec : OutputSections) {
1621 auto I = Config->SectionStartMap.find(Sec->Name);1703 auto I = Config->SectionStartMap.find(Sec->Name);
...@@ -1628,10 +1710,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1628,10 +1710,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1628 // particularly relevant.1710 // particularly relevant.
1629 Out::ElfHeader->SectionIndex = 1;1711 Out::ElfHeader->SectionIndex = 1;
16301712
1631 unsigned I = 1;1713 for (size_t I = 0, E = OutputSections.size(); I != E; ++I) {
1632 for (OutputSection *Sec : OutputSections) {1714 OutputSection *Sec = OutputSections[I];
1633 Sec->SectionIndex = I++;1715 Sec->SectionIndex = I + 1;
1634 Sec->ShName = InX::ShStrTab->addString(Sec->Name);1716 Sec->ShName = In.ShStrTab->addString(Sec->Name);
1635 }1717 }
16361718
1637 // Binary and relocatable output does not have PHDRS.1719 // Binary and relocatable output does not have PHDRS.
...@@ -1641,6 +1723,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1641,6 +1723,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1641 Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();1723 Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
1642 addPtArmExid(Phdrs);1724 addPtArmExid(Phdrs);
1643 Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();1725 Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
1726
1727 // Find the TLS segment. This happens before the section layout loop so that
1728 // Android relocation packing can look up TLS symbol addresses.
1729 for (PhdrEntry *P : Phdrs)
1730 if (P->p_type == PT_TLS)
1731 Out::TlsPhdr = P;
1644 }1732 }
16451733
1646 // Some symbols are defined in term of program headers. Now that we1734 // Some symbols are defined in term of program headers. Now that we
...@@ -1649,15 +1737,30 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1649,15 +1737,30 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16491737
1650 // Dynamic section must be the last one in this list and dynamic1738 // Dynamic section must be the last one in this list and dynamic
1651 // symbol table section (DynSymTab) must be the first one.1739 // symbol table section (DynSymTab) must be the first one.
1652 applySynthetic(1740 finalizeSynthetic(In.DynSymTab);
1653 {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab,1741 finalizeSynthetic(In.Bss);
1654 InX::HashTab, InX::SymTab, InX::SymTabShndx, InX::ShStrTab,1742 finalizeSynthetic(In.BssRelRo);
1655 InX::StrTab, In<ELFT>::VerDef, InX::DynStrTab, InX::Got,1743 finalizeSynthetic(In.GnuHashTab);
1656 InX::MipsGot, InX::IgotPlt, InX::GotPlt, InX::RelaDyn,1744 finalizeSynthetic(In.HashTab);
1657 InX::RelrDyn, InX::RelaIplt, InX::RelaPlt, InX::Plt,1745 finalizeSynthetic(In.SymTabShndx);
1658 InX::Iplt, InX::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed,1746 finalizeSynthetic(In.ShStrTab);
1659 InX::Dynamic},1747 finalizeSynthetic(In.StrTab);
1660 [](SyntheticSection *SS) { SS->finalizeContents(); });1748 finalizeSynthetic(In.VerDef);
1749 finalizeSynthetic(In.DynStrTab);
1750 finalizeSynthetic(In.Got);
1751 finalizeSynthetic(In.MipsGot);
1752 finalizeSynthetic(In.IgotPlt);
1753 finalizeSynthetic(In.GotPlt);
1754 finalizeSynthetic(In.RelaDyn);
1755 finalizeSynthetic(In.RelrDyn);
1756 finalizeSynthetic(In.RelaIplt);
1757 finalizeSynthetic(In.RelaPlt);
1758 finalizeSynthetic(In.Plt);
1759 finalizeSynthetic(In.Iplt);
1760 finalizeSynthetic(In.EhFrameHdr);
1761 finalizeSynthetic(InX<ELFT>::VerSym);
1762 finalizeSynthetic(InX<ELFT>::VerNeed);
1763 finalizeSynthetic(In.Dynamic);
16611764
1662 if (!Script->HasSectionsCommand && !Config->Relocatable)1765 if (!Script->HasSectionsCommand && !Config->Relocatable)
1663 fixSectionAlignments();1766 fixSectionAlignments();
...@@ -1666,37 +1769,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1666,37 +1769,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1666 // needs to be resolved before any other address dependent operation.1769 // needs to be resolved before any other address dependent operation.
1667 resolveShfLinkOrder();1770 resolveShfLinkOrder();
16681771
1669 // Some architectures need to generate content that depends on the address1772 // Jump instructions in many ISAs have small displacements, and therefore they
1670 // of InputSections. For example some architectures use small displacements1773 // cannot jump to arbitrary addresses in memory. For example, RISC-V JAL
1671 // for jump instructions that is the linker's responsibility for creating1774 // instruction can target only +-1 MiB from PC. It is a linker's
1672 // range extension thunks for. As the generation of the content may also1775 // responsibility to create and insert small pieces of code between sections
1673 // alter InputSection addresses we must converge to a fixed point.1776 // to extend the ranges if jump targets are out of range. Such code pieces are
1674 if (Target->NeedsThunks || Config->AndroidPackDynRelocs ||1777 // called "thunks".
1675 Config->RelrPackDynRelocs) {1778 //
1676 ThunkCreator TC;1779 // We add thunks at this stage. We couldn't do this before this point because
1677 AArch64Err843419Patcher A64P;1780 // this is the earliest point where we know sizes of sections and their
1678 bool Changed;1781 // layouts (that are needed to determine if jump targets are in range).
1679 do {1782 maybeAddThunks();
1680 Script->assignAddresses();
1681 Changed = false;
1682 if (Target->NeedsThunks)
1683 Changed |= TC.createThunks(OutputSections);
1684 if (Config->FixCortexA53Errata843419) {
1685 if (Changed)
1686 Script->assignAddresses();
1687 Changed |= A64P.createFixes();
1688 }
1689 if (InX::MipsGot)
1690 InX::MipsGot->updateAllocSize();
1691 Changed |= InX::RelaDyn->updateAllocSize();
1692 if (InX::RelrDyn)
1693 Changed |= InX::RelrDyn->updateAllocSize();
1694 } while (Changed);
1695 }
16961783
1697 // createThunks may have added local symbols to the static symbol table1784 // maybeAddThunks may have added local symbols to the static symbol table.
1698 applySynthetic({InX::SymTab},1785 finalizeSynthetic(In.SymTab);
1699 [](SyntheticSection *SS) { SS->postThunkContents(); });1786 finalizeSynthetic(In.PPC64LongBranchTarget);
17001787
1701 // Fill other section headers. The dynamic table is finalized1788 // Fill other section headers. The dynamic table is finalized
1702 // at the end because some tags like RELSZ depend on result1789 // at the end because some tags like RELSZ depend on result
...@@ -1705,6 +1792,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {...@@ -1705,6 +1792,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1705 Sec->finalize<ELFT>();1792 Sec->finalize<ELFT>();
1706}1793}
17071794
1795// Ensure data sections are not mixed with executable sections when
1796// -execute-only is used. -execute-only is a feature to make pages executable
1797// but not readable, and the feature is currently supported only on AArch64.
1798template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
1799 if (!Config->ExecuteOnly)
1800 return;
1801
1802 for (OutputSection *OS : OutputSections)
1803 if (OS->Flags & SHF_EXECINSTR)
1804 for (InputSection *IS : getInputSections(OS))
1805 if (!(IS->Flags & SHF_EXECINSTR))
1806 error("cannot place " + toString(IS) + " into " + toString(OS->Name) +
1807 ": -execute-only does not support intermingling data and code");
1808}
1809
1708// The linker is expected to define SECNAME_start and SECNAME_end1810// The linker is expected to define SECNAME_start and SECNAME_end
1709// symbols for a few sections. This function defines them.1811// symbols for a few sections. This function defines them.
1710template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {1812template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
...@@ -1721,9 +1823,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {...@@ -1721,9 +1823,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
1721 // program to fail to link due to relocation overflow, if their1823 // program to fail to link due to relocation overflow, if their
1722 // program text is above 2 GiB. We use the address of the .text1824 // program text is above 2 GiB. We use the address of the .text
1723 // section instead to prevent that failure.1825 // section instead to prevent that failure.
1826 //
1827 // In a rare sitaution, .text section may not exist. If that's the
1828 // case, use the image base address as a last resort.
1724 OutputSection *Default = findSection(".text");1829 OutputSection *Default = findSection(".text");
1725 if (!Default)1830 if (!Default)
1726 Default = Out::ElfHeader;1831 Default = Out::ElfHeader;
1832
1727 auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {1833 auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
1728 if (OS) {1834 if (OS) {
1729 addOptionalRegular(Start, OS, 0);1835 addOptionalRegular(Start, OS, 0);
...@@ -1763,7 +1869,7 @@ static bool needsPtLoad(OutputSection *Sec) {...@@ -1763,7 +1869,7 @@ static bool needsPtLoad(OutputSection *Sec) {
1763 // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is1869 // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
1764 // responsible for allocating space for them, not the PT_LOAD that1870 // responsible for allocating space for them, not the PT_LOAD that
1765 // contains the TLS initialization image.1871 // contains the TLS initialization image.
1766 if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS)1872 if ((Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS)
1767 return false;1873 return false;
1768 return true;1874 return true;
1769}1875}
...@@ -1841,9 +1947,8 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {...@@ -1841,9 +1947,8 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
1841 Ret.push_back(TlsHdr);1947 Ret.push_back(TlsHdr);
18421948
1843 // Add an entry for .dynamic.1949 // Add an entry for .dynamic.
1844 if (InX::DynSymTab)1950 if (OutputSection *Sec = In.Dynamic->getParent())
1845 AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())1951 AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
1846 ->add(InX::Dynamic->getParent());
18471952
1848 // PT_GNU_RELRO includes all sections that should be marked as1953 // PT_GNU_RELRO includes all sections that should be marked as
1849 // read-only by dynamic linker after proccessing relocations.1954 // read-only by dynamic linker after proccessing relocations.
...@@ -1871,10 +1976,10 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {...@@ -1871,10 +1976,10 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
1871 Ret.push_back(RelRo);1976 Ret.push_back(RelRo);
18721977
1873 // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.1978 // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
1874 if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() &&1979 if (!In.EhFrame->empty() && In.EhFrameHdr && In.EhFrame->getParent() &&
1875 InX::EhFrameHdr->getParent())1980 In.EhFrameHdr->getParent())
1876 AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags())1981 AddHdr(PT_GNU_EH_FRAME, In.EhFrameHdr->getParent()->getPhdrFlags())
1877 ->add(InX::EhFrameHdr->getParent());1982 ->add(In.EhFrameHdr->getParent());
18781983
1879 // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes1984 // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
1880 // the dynamic linker fill the segment with random data.1985 // the dynamic linker fill the segment with random data.
...@@ -1945,77 +2050,77 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {...@@ -1945,77 +2050,77 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
1945 for (const PhdrEntry *P : Phdrs) {2050 for (const PhdrEntry *P : Phdrs) {
1946 if (P->p_type != PT_GNU_RELRO)2051 if (P->p_type != PT_GNU_RELRO)
1947 continue;2052 continue;
2053
1948 if (P->FirstSec)2054 if (P->FirstSec)
1949 PageAlign(P->FirstSec);2055 PageAlign(P->FirstSec);
2056
1950 // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we2057 // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
1951 // have to align it to a page.2058 // have to align it to a page.
1952 auto End = OutputSections.end();2059 auto End = OutputSections.end();
1953 auto I = std::find(OutputSections.begin(), End, P->LastSec);2060 auto I = std::find(OutputSections.begin(), End, P->LastSec);
1954 if (I == End || (I + 1) == End)2061 if (I == End || (I + 1) == End)
1955 continue;2062 continue;
2063
1956 OutputSection *Cmd = (*(I + 1));2064 OutputSection *Cmd = (*(I + 1));
1957 if (needsPtLoad(Cmd))2065 if (needsPtLoad(Cmd))
1958 PageAlign(Cmd);2066 PageAlign(Cmd);
1959 }2067 }
1960}2068}
19612069
1962// Adjusts the file alignment for a given output section and returns2070// Compute an in-file position for a given section. The file offset must be the
1963// its new file offset. The file offset must be the same with its2071// same with its virtual address modulo the page size, so that the loader can
1964// virtual address (modulo the page size) so that the loader can load2072// load executables without any address adjustment.
1965// executables without any address adjustment.2073static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) {
1966static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) {2074 // File offsets are not significant for .bss sections. By convention, we keep
1967 OutputSection *First = Cmd->PtLoad ? Cmd->PtLoad->FirstSec : nullptr;2075 // section offsets monotonically increasing rather than setting to zero.
1968 // The first section in a PT_LOAD has to have congruent offset and address2076 if (OS->Type == SHT_NOBITS)
1969 // module the page size.
1970 if (Cmd == First)
1971 return alignTo(Off, std::max<uint64_t>(Cmd->Alignment, Config->MaxPageSize),
1972 Cmd->Addr);
1973
1974 // For SHT_NOBITS we don't want the alignment of the section to impact the
1975 // offset of the sections that follow. Since nothing seems to care about the
1976 // sh_offset of the SHT_NOBITS section itself, just ignore it.
1977 if (Cmd->Type == SHT_NOBITS)
1978 return Off;2077 return Off;
19792078
1980 // If the section is not in a PT_LOAD, we just have to align it.2079 // If the section is not in a PT_LOAD, we just have to align it.
1981 if (!Cmd->PtLoad)2080 if (!OS->PtLoad)
1982 return alignTo(Off, Cmd->Alignment);2081 return alignTo(Off, OS->Alignment);
2082
2083 // The first section in a PT_LOAD has to have congruent offset and address
2084 // module the page size.
2085 OutputSection *First = OS->PtLoad->FirstSec;
2086 if (OS == First) {
2087 uint64_t Alignment = std::max<uint64_t>(OS->Alignment, Config->MaxPageSize);
2088 return alignTo(Off, Alignment, OS->Addr);
2089 }
19832090
1984 // If two sections share the same PT_LOAD the file offset is calculated2091 // If two sections share the same PT_LOAD the file offset is calculated
1985 // using this formula: Off2 = Off1 + (VA2 - VA1).2092 // using this formula: Off2 = Off1 + (VA2 - VA1).
1986 return First->Offset + Cmd->Addr - First->Addr;2093 return First->Offset + OS->Addr - First->Addr;
1987}2094}
19882095
1989static uint64_t setOffset(OutputSection *Cmd, uint64_t Off) {2096// Set an in-file position to a given section and returns the end position of
1990 Off = getFileAlignment(Off, Cmd);2097// the section.
1991 Cmd->Offset = Off;2098static uint64_t setFileOffset(OutputSection *OS, uint64_t Off) {
2099 Off = computeFileOffset(OS, Off);
2100 OS->Offset = Off;
19922101
1993 // For SHT_NOBITS we should not count the size.2102 if (OS->Type == SHT_NOBITS)
1994 if (Cmd->Type == SHT_NOBITS)
1995 return Off;2103 return Off;
19962104 return Off + OS->Size;
1997 return Off + Cmd->Size;
1998}2105}
19992106
2000template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {2107template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
2001 uint64_t Off = 0;2108 uint64_t Off = 0;
2002 for (OutputSection *Sec : OutputSections)2109 for (OutputSection *Sec : OutputSections)
2003 if (Sec->Flags & SHF_ALLOC)2110 if (Sec->Flags & SHF_ALLOC)
2004 Off = setOffset(Sec, Off);2111 Off = setFileOffset(Sec, Off);
2005 FileSize = alignTo(Off, Config->Wordsize);2112 FileSize = alignTo(Off, Config->Wordsize);
2006}2113}
20072114
2008static std::string rangeToString(uint64_t Addr, uint64_t Len) {2115static std::string rangeToString(uint64_t Addr, uint64_t Len) {
2009 if (Len == 0)
2010 return "<empty range at 0x" + utohexstr(Addr) + ">";
2011 return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";2116 return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
2012}2117}
20132118
2014// Assign file offsets to output sections.2119// Assign file offsets to output sections.
2015template <class ELFT> void Writer<ELFT>::assignFileOffsets() {2120template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
2016 uint64_t Off = 0;2121 uint64_t Off = 0;
2017 Off = setOffset(Out::ElfHeader, Off);2122 Off = setFileOffset(Out::ElfHeader, Off);
2018 Off = setOffset(Out::ProgramHeaders, Off);2123 Off = setFileOffset(Out::ProgramHeaders, Off);
20192124
2020 PhdrEntry *LastRX = nullptr;2125 PhdrEntry *LastRX = nullptr;
2021 for (PhdrEntry *P : Phdrs)2126 for (PhdrEntry *P : Phdrs)
...@@ -2023,9 +2128,10 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {...@@ -2023,9 +2128,10 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
2023 LastRX = P;2128 LastRX = P;
20242129
2025 for (OutputSection *Sec : OutputSections) {2130 for (OutputSection *Sec : OutputSections) {
2026 Off = setOffset(Sec, Off);2131 Off = setFileOffset(Sec, Off);
2027 if (Script->HasSectionsCommand)2132 if (Script->HasSectionsCommand)
2028 continue;2133 continue;
2134
2029 // If this is a last section of the last executable segment and that2135 // If this is a last section of the last executable segment and that
2030 // segment is the last loadable segment, align the offset of the2136 // segment is the last loadable segment, align the offset of the
2031 // following section to avoid loading non-segments parts of the file.2137 // following section to avoid loading non-segments parts of the file.
...@@ -2050,7 +2156,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {...@@ -2050,7 +2156,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
2050 continue;2156 continue;
2051 if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))2157 if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
2052 error("unable to place section " + Sec->Name + " at file offset " +2158 error("unable to place section " + Sec->Name + " at file offset " +
2053 rangeToString(Sec->Offset, Sec->Offset + Sec->Size) +2159 rangeToString(Sec->Offset, Sec->Size) +
2054 "; check your linker script for overflows");2160 "; check your linker script for overflows");
2055 }2161 }
2056}2162}
...@@ -2061,19 +2167,23 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {...@@ -2061,19 +2167,23 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
2061 for (PhdrEntry *P : Phdrs) {2167 for (PhdrEntry *P : Phdrs) {
2062 OutputSection *First = P->FirstSec;2168 OutputSection *First = P->FirstSec;
2063 OutputSection *Last = P->LastSec;2169 OutputSection *Last = P->LastSec;
2170
2064 if (First) {2171 if (First) {
2065 P->p_filesz = Last->Offset - First->Offset;2172 P->p_filesz = Last->Offset - First->Offset;
2066 if (Last->Type != SHT_NOBITS)2173 if (Last->Type != SHT_NOBITS)
2067 P->p_filesz += Last->Size;2174 P->p_filesz += Last->Size;
2175
2068 P->p_memsz = Last->Addr + Last->Size - First->Addr;2176 P->p_memsz = Last->Addr + Last->Size - First->Addr;
2069 P->p_offset = First->Offset;2177 P->p_offset = First->Offset;
2070 P->p_vaddr = First->Addr;2178 P->p_vaddr = First->Addr;
2179
2071 if (!P->HasLMA)2180 if (!P->HasLMA)
2072 P->p_paddr = First->getLMA();2181 P->p_paddr = First->getLMA();
2073 }2182 }
2074 if (P->p_type == PT_LOAD)2183
2184 if (P->p_type == PT_LOAD) {
2075 P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);2185 P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);
2076 else if (P->p_type == PT_GNU_RELRO) {2186 } else if (P->p_type == PT_GNU_RELRO) {
2077 P->p_align = 1;2187 P->p_align = 1;
2078 // The glibc dynamic loader rounds the size down, so we need to round up2188 // The glibc dynamic loader rounds the size down, so we need to round up
2079 // to protect the last page. This is a no-op on FreeBSD which always2189 // to protect the last page. This is a no-op on FreeBSD which always
...@@ -2081,12 +2191,22 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {...@@ -2081,12 +2191,22 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
2081 P->p_memsz = alignTo(P->p_memsz, Target->PageSize);2191 P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
2082 }2192 }
20832193
2084 // The TLS pointer goes after PT_TLS. At least glibc will align it,2194 if (P->p_type == PT_TLS && P->p_memsz) {
2085 // so round up the size to make sure the offsets are correct.2195 if (!Config->Shared &&
2086 if (P->p_type == PT_TLS) {2196 (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) {
2087 Out::TlsPhdr = P;2197 // On ARM/AArch64, reserve extra space (8 words) between the thread
2088 if (P->p_memsz)2198 // pointer and an executable's TLS segment by overaligning the segment.
2089 P->p_memsz = alignTo(P->p_memsz, P->p_align);2199 // This reservation is needed for backwards compatibility with Android's
2200 // TCB, which allocates several slots after the thread pointer (e.g.
2201 // TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also
2202 // done on other operating systems.
2203 P->p_align = std::max<uint64_t>(P->p_align, Config->Wordsize * 8);
2204 }
2205
2206 // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
2207 // will align it, so round up the size to make sure the offsets are
2208 // correct.
2209 P->p_memsz = alignTo(P->p_memsz, P->p_align);
2090 }2210 }
2091 }2211 }
2092}2212}
...@@ -2103,10 +2223,9 @@ struct SectionOffset {...@@ -2103,10 +2223,9 @@ struct SectionOffset {
2103// load and virtual adresses).2223// load and virtual adresses).
2104static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,2224static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
2105 bool IsVirtualAddr) {2225 bool IsVirtualAddr) {
2106 llvm::sort(Sections.begin(), Sections.end(),2226 llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) {
2107 [=](const SectionOffset &A, const SectionOffset &B) {2227 return A.Offset < B.Offset;
2108 return A.Offset < B.Offset;2228 });
2109 });
21102229
2111 // Finding overlap is easy given a vector is sorted by start position.2230 // Finding overlap is easy given a vector is sorted by start position.
2112 // If an element starts before the end of the previous element, they overlap.2231 // If an element starts before the end of the previous element, they overlap.
...@@ -2150,7 +2269,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {...@@ -2150,7 +2269,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
2150 // file so we skip any non-allocated sections in that case.2269 // file so we skip any non-allocated sections in that case.
2151 std::vector<SectionOffset> FileOffs;2270 std::vector<SectionOffset> FileOffs;
2152 for (OutputSection *Sec : OutputSections)2271 for (OutputSection *Sec : OutputSections)
2153 if (0 < Sec->Size && Sec->Type != SHT_NOBITS &&2272 if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&
2154 (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))2273 (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
2155 FileOffs.push_back({Sec, Sec->Offset});2274 FileOffs.push_back({Sec, Sec->Offset});
2156 checkOverlap("file", FileOffs, false);2275 checkOverlap("file", FileOffs, false);
...@@ -2168,7 +2287,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {...@@ -2168,7 +2287,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
2168 // ranges in the file.2287 // ranges in the file.
2169 std::vector<SectionOffset> VMAs;2288 std::vector<SectionOffset> VMAs;
2170 for (OutputSection *Sec : OutputSections)2289 for (OutputSection *Sec : OutputSections)
2171 if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))2290 if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
2172 VMAs.push_back({Sec, Sec->Addr});2291 VMAs.push_back({Sec, Sec->Addr});
2173 checkOverlap("virtual address", VMAs, true);2292 checkOverlap("virtual address", VMAs, true);
21742293
...@@ -2177,7 +2296,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {...@@ -2177,7 +2296,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
2177 // script with AT().2296 // script with AT().
2178 std::vector<SectionOffset> LMAs;2297 std::vector<SectionOffset> LMAs;
2179 for (OutputSection *Sec : OutputSections)2298 for (OutputSection *Sec : OutputSections)
2180 if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))2299 if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
2181 LMAs.push_back({Sec, Sec->getLMA()});2300 LMAs.push_back({Sec, Sec->getLMA()});
2182 checkOverlap("load address", LMAs, false);2301 checkOverlap("load address", LMAs, false);
2183}2302}
...@@ -2190,7 +2309,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {...@@ -2190,7 +2309,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
2190// 4. the number represented by the entry symbol, if it is a number;2309// 4. the number represented by the entry symbol, if it is a number;
2191// 5. the address of the first byte of the .text section, if present;2310// 5. the address of the first byte of the .text section, if present;
2192// 6. the address 0.2311// 6. the address 0.
2193template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {2312static uint64_t getEntryAddr() {
2194 // Case 1, 2 or 32313 // Case 1, 2 or 3
2195 if (Symbol *B = Symtab->find(Config->Entry))2314 if (Symbol *B = Symtab->find(Config->Entry))
2196 return B->getVA();2315 return B->getVA();
...@@ -2233,6 +2352,7 @@ static uint8_t getAbiVersion() {...@@ -2233,6 +2352,7 @@ static uint8_t getAbiVersion() {
22332352
2234template <class ELFT> void Writer<ELFT>::writeHeader() {2353template <class ELFT> void Writer<ELFT>::writeHeader() {
2235 uint8_t *Buf = Buffer->getBufferStart();2354 uint8_t *Buf = Buffer->getBufferStart();
2355
2236 // For executable segments, the trap instructions are written before writing2356 // For executable segments, the trap instructions are written before writing
2237 // the header. Setting Elf header bytes to zero ensures that any unused bytes2357 // the header. Setting Elf header bytes to zero ensures that any unused bytes
2238 // in header are zero-cleared, instead of having trap instructions.2358 // in header are zero-cleared, instead of having trap instructions.
...@@ -2291,7 +2411,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {...@@ -2291,7 +2411,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
2291 else2411 else
2292 EHdr->e_shnum = Num;2412 EHdr->e_shnum = Num;
22932413
2294 uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex;2414 uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
2295 if (StrTabIndex >= SHN_LORESERVE) {2415 if (StrTabIndex >= SHN_LORESERVE) {
2296 SHdrs->sh_link = StrTabIndex;2416 SHdrs->sh_link = StrTabIndex;
2297 EHdr->e_shstrndx = SHN_XINDEX;2417 EHdr->e_shstrndx = SHN_XINDEX;
...@@ -2305,7 +2425,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {...@@ -2305,7 +2425,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
23052425
2306// Open a result file.2426// Open a result file.
2307template <class ELFT> void Writer<ELFT>::openFile() {2427template <class ELFT> void Writer<ELFT>::openFile() {
2308 if (!Config->Is64 && FileSize > UINT32_MAX) {2428 uint64_t MaxSize = Config->Is64 ? INT64_MAX : UINT32_MAX;
2429 if (MaxSize < FileSize) {
2309 error("output file too large: " + Twine(FileSize) + " bytes");2430 error("output file too large: " + Twine(FileSize) + " bytes");
2310 return;2431 return;
2311 }2432 }
...@@ -2370,8 +2491,8 @@ template <class ELFT> void Writer<ELFT>::writeSections() {...@@ -2370,8 +2491,8 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
2370 uint8_t *Buf = Buffer->getBufferStart();2491 uint8_t *Buf = Buffer->getBufferStart();
23712492
2372 OutputSection *EhFrameHdr = nullptr;2493 OutputSection *EhFrameHdr = nullptr;
2373 if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())2494 if (In.EhFrameHdr && !In.EhFrameHdr->empty())
2374 EhFrameHdr = InX::EhFrameHdr->getParent();2495 EhFrameHdr = In.EhFrameHdr->getParent();
23752496
2376 // In -r or -emit-relocs mode, write the relocation sections first as in2497 // In -r or -emit-relocs mode, write the relocation sections first as in
2377 // ELf_Rel targets we might find out that we need to modify the relocated2498 // ELf_Rel targets we might find out that we need to modify the relocated
...@@ -2391,13 +2512,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {...@@ -2391,13 +2512,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
2391}2512}
23922513
2393template <class ELFT> void Writer<ELFT>::writeBuildId() {2514template <class ELFT> void Writer<ELFT>::writeBuildId() {
2394 if (!InX::BuildId || !InX::BuildId->getParent())2515 if (!In.BuildId || !In.BuildId->getParent())
2395 return;2516 return;
23962517
2397 // Compute a hash of all sections of the output file.2518 // Compute a hash of all sections of the output file.
2398 uint8_t *Start = Buffer->getBufferStart();2519 uint8_t *Start = Buffer->getBufferStart();
2399 uint8_t *End = Start + FileSize;2520 uint8_t *End = Start + FileSize;
2400 InX::BuildId->writeBuildId({Start, End});2521 In.BuildId->writeBuildId({Start, End});
2401}2522}
24022523
2403template void elf::writeResult<ELF32LE>();2524template void elf::writeResult<ELF32LE>();
deps/lld/LICENSE.TXT+1-1
...@@ -4,7 +4,7 @@ lld License...@@ -4,7 +4,7 @@ lld License
4University of Illinois/NCSA4University of Illinois/NCSA
5Open Source License5Open Source License
66
7Copyright (c) 2011-2018 by the contributors listed in CREDITS.TXT7Copyright (c) 2011-2019 by the contributors listed in CREDITS.TXT
8All rights reserved.8All rights reserved.
99
10Developed by:10Developed by:
deps/lld/MinGW/Driver.cpp+27-4
...@@ -6,9 +6,27 @@...@@ -6,9 +6,27 @@
6// License. See LICENSE.TXT for details.6// License. See LICENSE.TXT for details.
7//7//
8//===----------------------------------------------------------------------===//8//===----------------------------------------------------------------------===//
9///9//
10/// GNU ld style linker driver for COFF currently supporting mingw-w64.10// MinGW is a GNU development environment for Windows. It consists of GNU
11///11// tools such as GCC and GNU ld. Unlike Cygwin, there's no POSIX-compatible
12// layer, as it aims to be a native development toolchain.
13//
14// lld/MinGW is a drop-in replacement for GNU ld/MinGW.
15//
16// Being a native development tool, a MinGW linker is not very different from
17// Microsoft link.exe, so a MinGW linker can be implemented as a thin wrapper
18// for lld/COFF. This driver takes Unix-ish command line options, translates
19// them to Windows-ish ones, and then passes them to lld/COFF.
20//
21// When this driver calls the lld/COFF driver, it passes a hidden option
22// "-lldmingw" along with other user-supplied options, to run the lld/COFF
23// linker in "MinGW mode".
24//
25// There are subtle differences between MS link.exe and GNU ld/MinGW, and GNU
26// ld/MinGW implements a few GNU-specific features. Such features are directly
27// implemented in lld/COFF and enabled only when the linker is running in MinGW
28// mode.
29//
12//===----------------------------------------------------------------------===//30//===----------------------------------------------------------------------===//
1331
14#include "lld/Common/Driver.h"32#include "lld/Common/Driver.h"
...@@ -212,9 +230,14 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {...@@ -212,9 +230,14 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
212 else230 else
213 Add("-alternatename:__image_base__=__ImageBase");231 Add("-alternatename:__image_base__=__ImageBase");
214232
233 for (auto *A : Args.filtered(OPT_require_defined))
234 Add("-include:" + StringRef(A->getValue()));
235
215 std::vector<StringRef> SearchPaths;236 std::vector<StringRef> SearchPaths;
216 for (auto *A : Args.filtered(OPT_L))237 for (auto *A : Args.filtered(OPT_L)) {
217 SearchPaths.push_back(A->getValue());238 SearchPaths.push_back(A->getValue());
239 Add("-libpath:" + StringRef(A->getValue()));
240 }
218241
219 StringRef Prefix = "";242 StringRef Prefix = "";
220 bool Static = false;243 bool Static = false;
deps/lld/MinGW/Options.td+9
...@@ -40,6 +40,9 @@ def strip_debug: F<"strip-debug">,...@@ -40,6 +40,9 @@ def strip_debug: F<"strip-debug">,
40def whole_archive: F<"whole-archive">,40def whole_archive: F<"whole-archive">,
41 HelpText<"Include all object files for following archives">;41 HelpText<"Include all object files for following archives">;
42def verbose: F<"verbose">, HelpText<"Verbose mode">;42def verbose: F<"verbose">, HelpText<"Verbose mode">;
43def require_defined: S<"require-defined">,
44 HelpText<"Force symbol to be added to symbol table as an undefined one">;
45def require_defined_eq: J<"require-defined=">, Alias<require_defined>;
4346
44// LLD specific options47// LLD specific options
45def _HASH_HASH_HASH : Flag<["-"], "###">,48def _HASH_HASH_HASH : Flag<["-"], "###">,
...@@ -75,3 +78,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">;...@@ -75,3 +78,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">;
75def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;78def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
76def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;79def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
77def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;80def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;
81
82// Ignored options
83def: S<"plugin">;
84def: J<"plugin=">;
85def: S<"plugin-opt">;
86def: J<"plugin-opt=">;
deps/lld/docs/NewLLD.rst+7-7
...@@ -53,7 +53,7 @@ between speed, simplicity and extensibility....@@ -53,7 +53,7 @@ between speed, simplicity and extensibility.
53 until we need them to continue linking.53 until we need them to continue linking.
54 When we need to do some costly operation (such as looking up54 When we need to do some costly operation (such as looking up
55 a hash table for each symbol), we do it only once.55 a hash table for each symbol), we do it only once.
56 We obtain a handler (which is typically just a pointer to actual data)56 We obtain a handle (which is typically just a pointer to actual data)
57 on the first operation and use it throughout the process.57 on the first operation and use it throughout the process.
5858
59* Efficient archive file handling59* Efficient archive file handling
...@@ -90,18 +90,18 @@ between speed, simplicity and extensibility....@@ -90,18 +90,18 @@ between speed, simplicity and extensibility.
90 `--end-group`, to let the linker loop over the files between the options until90 `--end-group`, to let the linker loop over the files between the options until
91 no new symbols are added to the set.91 no new symbols are added to the set.
9292
93 Visiting the same archive files multiple makes the linker slower.93 Visiting the same archive files multiple times makes the linker slower.
9494
95 Here is how LLD approaches the problem. Instead of memorizing only undefined95 Here is how LLD approaches the problem. Instead of memorizing only undefined
96 symbols, we program LLD so that it memorizes all symbols. When it sees an96 symbols, we program LLD so that it memorizes all symbols. When it sees an
97 undefined symbol that can be resolved by extracting an object file from an97 undefined symbol that can be resolved by extracting an object file from an
98 archive file it previously visited, it immediately extracts the file and link98 archive file it previously visited, it immediately extracts the file and links
99 it. It is doable because LLD does not forget symbols it have seen in archive99 it. It is doable because LLD does not forget symbols it has seen in archive
100 files.100 files.
101101
102 We believe that the LLD's way is efficient and easy to justify.102 We believe that LLD's way is efficient and easy to justify.
103103
104 The semantics of LLD's archive handling is different from the traditional104 The semantics of LLD's archive handling are different from the traditional
105 Unix's. You can observe it if you carefully craft archive files to exploit105 Unix's. You can observe it if you carefully craft archive files to exploit
106 it. However, in reality, we don't know any program that cannot link with our106 it. However, in reality, we don't know any program that cannot link with our
107 algorithm so far, so it's not going to cause trouble.107 algorithm so far, so it's not going to cause trouble.
...@@ -157,7 +157,7 @@ functions, the code of the linker should look obvious to you....@@ -157,7 +157,7 @@ functions, the code of the linker should look obvious to you.
157 - Undefined symbols represent undefined symbols, which need to be replaced by157 - Undefined symbols represent undefined symbols, which need to be replaced by
158 Defined symbols by the resolver until the link is complete.158 Defined symbols by the resolver until the link is complete.
159 - Lazy symbols represent symbols we found in archive file headers159 - Lazy symbols represent symbols we found in archive file headers
160 which can turn into Defined if we read archieve members.160 which can turn into Defined if we read archive members.
161161
162 There's only one Symbol instance for each unique symbol name. This uniqueness162 There's only one Symbol instance for each unique symbol name. This uniqueness
163 is guaranteed by the symbol table. As the resolver reads symbols from input163 is guaranteed by the symbol table. As the resolver reads symbols from input
deps/lld/docs/README.txt+1-4
...@@ -6,7 +6,4 @@ currently tested with Sphinx 1.1.3....@@ -6,7 +6,4 @@ currently tested with Sphinx 1.1.3.
66
7We currently use the 'nature' theme and a Beaker inspired structure.7We currently use the 'nature' theme and a Beaker inspired structure.
88
9To rebuild documents into html:9See sphinx_intro.rst for more details.
10
11 [/lld/docs]> make html
12
deps/lld/docs/Readers.rst+1-1
...@@ -74,7 +74,7 @@ files in parallel. Therefore, there should be no parsing state in you Reader...@@ -74,7 +74,7 @@ files in parallel. Therefore, there should be no parsing state in you Reader
74object. Any parsing state should be in ivars of your File subclass or in74object. Any parsing state should be in ivars of your File subclass or in
75some temporary object.75some temporary object.
7676
77The key method to implement in a reader is::77The key function to implement in a reader is::
7878
79 virtual error_code loadFile(LinkerInput &input,79 virtual error_code loadFile(LinkerInput &input,
80 std::vector<std::unique_ptr<File>> &result);80 std::vector<std::unique_ptr<File>> &result);
deps/lld/docs/ReleaseNotes.rst+80-12
...@@ -1,14 +1,19 @@...@@ -1,14 +1,19 @@
1=======================1=======================
2LLD 7.0.0 Release Notes2lld 8.0.0 Release Notes
3=======================3=======================
44
5.. contents::5.. contents::
6 :local:6 :local:
77
8.. warning::
9 These are in-progress notes for the upcoming LLVM 8.0.0 release.
10 Release notes for previous releases can be found on
11 `the Download Page <https://releases.llvm.org/download.html>`_.
12
8Introduction13Introduction
9============14============
1015
11This document contains the release notes for the lld linker, release 7.0.0.16This document contains the release notes for the lld linker, release 8.0.0.
12Here we describe the status of lld, including major improvements17Here we describe the status of lld, including major improvements
13from the previous release. All lld releases may be downloaded18from the previous release. All lld releases may be downloaded
14from the `LLVM releases web site <https://llvm.org/releases/>`_.19from the `LLVM releases web site <https://llvm.org/releases/>`_.
...@@ -19,23 +24,86 @@ Non-comprehensive list of changes in this release...@@ -19,23 +24,86 @@ Non-comprehensive list of changes in this release
19ELF Improvements24ELF Improvements
20----------------25----------------
2126
22* lld is now able to overcome MIPS GOT entries number limitation27* lld now supports RISC-V. (`r339364
23 and generate multi-GOT if necessary.28 <https://reviews.llvm.org/rL339364>`_)
29
30* Default image base address has changed from 65536 to 2 MiB for i386
31 and 4 MiB for AArch64 to make lld-generated executables work better
32 with automatic superpage promotion. FreeBSD can promote contiguous
33 non-superpages to a superpage if they are aligned to the superpage
34 size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
35
36* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
37 Hexagon ISA.
2438
25* lld is now able to produce MIPS position-independent executable (PIE).39* Initial MSP430 ISA support has landed.
2640
27* Fixed MIPS TLS GOT entries for local symbols in shared libraries.41* The following flags have been added: ``-z interpose``, ``-z global``
2842
29* Fixed calculation of MIPS GP relative relocations43* lld now uses the ``sigrie`` instruction as a trap instruction for
30 in case of relocatable output.44 MIPS targets.
3145
32COFF Improvements46COFF Improvements
33-----------------47-----------------
3448
35* Improved correctness of exporting mangled stdcall symbols.49* PDB GUID is set to hash of PDB contents instead to a random byte
50 sequence for build reproducibility.
51
52* ``/pdbsourcepath:`` is now also used to make ``"cwd"``, ``"exe"``, ``"pdb"``
53 in the env block of PDB outputs absolute if they are relative, and to make
54 paths to obj files referenced in PDB outputs absolute if they are relative.
55 Together with the previous item, this makes it possible to generate
56 executables and PDBs that are fully deterministic and independent of the
57 absolute path to the build directory, so that different machines building
58 the same code in different directories can produce exactly the same output.
59
60* The following flags have been added: ``/force:multiple``
61
62* lld now can link against import libraries produced by GNU tools.
63
64* lld can create thunks for ARM and ARM64, to allow linking larger images
65 (over 16 MB for ARM and over 128 MB for ARM64)
66
67* Several speed and memory usage improvements.
68
69* lld now creates debug info for typedefs.
70
71* lld can now link obj files produced by ``cl.exe /Z7 /Yc``.
72
73* lld now understands ``%_PDB%`` and ``%_EXT%`` in ``/pdbaltpath:``.
74
75* Undefined symbols are now printed in demangled form in addition to raw form.
76
77MinGW Improvements
78------------------
79
80* lld can now automatically import data variables from DLLs without the
81 use of the dllimport attribute.
82
83* lld can now use existing normal MinGW sysroots with import libraries and
84 CRT startup object files for GNU binutils. lld can handle most object
85 files produced by GCC, and thus works as a drop-in replacement for
86 ld.bfd in such environments. (There are known issues with linking crtend.o
87 from GCC in setups with DWARF exceptions though, where object files are
88 linked in a different order than with GNU ld, inserting a DWARF exception
89 table terminator too early.)
90
91* lld now supports COFF embedded directives for linking to nondefault
92 libraries, just like for the normal COFF target.
93
94* Actually generate a codeview build id signature, even if not creating a PDB.
95 Previously, the ``--build-id`` option did not actually generate a build id
96 unless ``--pdb`` was specified.
97
98MachO Improvements
99------------------
36100
37* Completed support for ARM64 relocations.101* Item 1.
38102
39* Added support for outputting PDB debug info for MinGW targets.103WebAssembly Improvements
104------------------------
40105
41* Improved compatibility of output binaries with GNU binutils objcopy/strip.106* Add initial support for creating shared libraries (-shared).
107 Note: The shared library format is still under active development and may
108 undergo significant changes in future versions.
109 See: https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
deps/lld/docs/WebAssembly.rst+92-14
...@@ -1,13 +1,10 @@...@@ -1,13 +1,10 @@
1WebAssembly lld port1WebAssembly lld port
2====================2====================
33
4Note: The WebAssembly port is still a work in progress and is be lacking
5certain features.
6
7The WebAssembly version of lld takes WebAssembly binaries as inputs and produces4The WebAssembly version of lld takes WebAssembly binaries as inputs and produces
8a WebAssembly binary as its output. For the most part this port tried to mimic5a WebAssembly binary as its output. For the most part it tries to mimic the
9the behaviour of traditional ELF linkers and specifically the ELF lld port.6behaviour of traditional ELF linkers and specifically the ELF lld port. Where
10Where possible that command line flags and the semantics should be the same.7possible that command line flags and the semantics should be the same.
118
129
13Object file format10Object file format
...@@ -23,14 +20,95 @@ currently requires enabling the experimental backed using...@@ -23,14 +20,95 @@ currently requires enabling the experimental backed using
23``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``.20``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``.
2421
2522
23Usage
24-----
25
26The WebAssembly version of lld is installed as **wasm-ld**. It shared many
27common linker flags with **ld.lld** but also includes several
28WebAssembly-specific options:
29
30.. option:: --no-entry
31
32 Don't search for the entry point symbol (by default ``_start``).
33
34.. option:: --export-table
35
36 Export the function table to the environment.
37
38.. option:: --import-table
39
40 Import the function table from the environment.
41
42.. option:: --export-all
43
44 Export all symbols (normally combined with --no-gc-sections)
45
46.. option:: --export-dynamic
47
48 When building an executable, export any non-hidden symbols. By default only
49 the entry point and any symbols marked with --export/--export-all are
50 exported.
51
52.. option:: --global-base=<value>
53
54 Address at which to place global data.
55
56.. option:: --no-merge-data-segments
57
58 Disable merging of data segments.
59
60.. option:: --stack-first
61
62 Place stack at start of linear memory rather than after data.
63
64.. option:: --compress-relocations
65
66 Relocation targets in the code section 5-bytes wide in order to potentially
67 occomate the largest LEB128 value. This option will cause the linker to
68 shirnk the code section to remove any padding from the final output. However
69 because it effects code offset, this option is not comatible with outputing
70 debug information.
71
72.. option:: --allow-undefined
73
74 Allow undefined symbols in linked binary.
75
76.. option:: --import-memory
77
78 Import memory from the environment.
79
80.. option:: --initial-memory=<value>
81
82 Initial size of the linear memory. Default: static data size.
83
84.. option:: --max-memory=<value>
85
86 Maximum size of the linear memory. Default: unlimited.
87
88By default the function table is neither imported nor exported, but defined
89for internal use only.
90
91When building shared libraries symbols are exported if they are marked
92as ``visibility=default``. When building executables only the entry point is
93exported by default. In addition any symbol included on the command line via
94``--export`` is also exported.
95
96Since WebAssembly is designed with size in mind the linker defaults to
97``--gc-sections`` which means that all unused functions and data segments will
98be stripped from the binary.
99
100The symbols which are preserved by default are:
101
102- The entry point (by default ``_start``).
103- Any symbol which is to be exported.
104- Any symbol transitively referenced by the above.
105
106
26Missing features107Missing features
27----------------108----------------
28109
29There are several key features that are not yet implement in the WebAssembly110- Merging of data section similar to ``SHF_MERGE`` in the ELF world is not
30ports:111 supported.
31112- No support for creating shared libraries. The spec for shared libraries in
32- COMDAT support. This means that support for C++ is still very limited.113 WebAssembly is still in flux:
33- Function stripping. Currently there is no support for ``--gc-sections`` so114 https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
34 functions and data from a given object will linked as a unit.
35- Section start/end symbols. The synthetic symbols that mark the start and
36 of data regions are not yet created in the output file.
deps/lld/docs/conf.py+2-2
...@@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year...@@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year
48# built documents.48# built documents.
49#49#
50# The short version.50# The short version.
51version = '7'51version = '8'
52# The full version, including alpha/beta/rc tags.52# The full version, including alpha/beta/rc tags.
53release = '7'53release = '8'
5454
55# The language for content autogenerated by Sphinx. Refer to documentation55# The language for content autogenerated by Sphinx. Refer to documentation
56# for a list of supported languages.56# for a list of supported languages.
deps/lld/docs/index.rst+10-11
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1LLD - The LLVM Linker1LLD - The LLVM Linker
2=====================2=====================
33
4LLD is a linker from the LLVM project. That is a drop-in replacement4LLD is a linker from the LLVM project that is a drop-in replacement
5for system linkers and runs much faster than them. It also provides5for system linkers and runs much faster than them. It also provides
6features that are useful for toolchain developers.6features that are useful for toolchain developers.
77
...@@ -17,7 +17,7 @@ read :doc:`AtomLLD`....@@ -17,7 +17,7 @@ read :doc:`AtomLLD`.
17Features17Features
18--------18--------
1919
20- LLD is a drop-in replacement for the GNU linkers. That accepts the20- LLD is a drop-in replacement for the GNU linkers that accepts the
21 same command line arguments and linker scripts as GNU.21 same command line arguments and linker scripts as GNU.
2222
23 We are currently working closely with the FreeBSD project to make23 We are currently working closely with the FreeBSD project to make
...@@ -30,29 +30,27 @@ Features...@@ -30,29 +30,27 @@ Features
30 <https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.30 <https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.
3131
32- LLD is very fast. When you link a large program on a multicore32- LLD is very fast. When you link a large program on a multicore
33 machine, you can expect that LLD runs more than twice as fast as GNU33 machine, you can expect that LLD runs more than twice as fast as the GNU
34 gold linker. Your milage may vary, though.34 gold linker. Your milage may vary, though.
3535
36- It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,36- It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,
37 ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.37 ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.
38 Among these, x86-64 is the most well-supported target and have38 Among these, x86-64, AArch64, and ARM (>= v6) are production quality.
39 reached production quality. AArch64 and MIPS seem decent too. x8639 MIPS seems decent too. x86 should be OK but is not well tested yet.
40 should be OK but not well tested yet. ARM support is being developed
41 actively.
4240
43- It is always a cross-linker, meaning that it always supports all the41- It is always a cross-linker, meaning that it always supports all the
44 above targets however it was built. In fact, we don't provide a42 above targets however it was built. In fact, we don't provide a
45 build-time option to enable/disable each target. This should make it43 build-time option to enable/disable each target. This should make it
46 easy to use our linker as part of a cross-compile toolchain.44 easy to use our linker as part of a cross-compile toolchain.
4745
48- You can embed LLD to your program to eliminate dependency to46- You can embed LLD in your program to eliminate dependencies on
49 external linkers. All you have to do is to construct object files47 external linkers. All you have to do is to construct object files
50 and command line arguments just like you would do to invoke an48 and command line arguments just like you would do to invoke an
51 external linker and then call the linker's main function,49 external linker and then call the linker's main function,
52 ``lld::elf::link``, from your code.50 ``lld::elf::link``, from your code.
5351
54- It is small. We are using LLVM libObject library to read from object52- It is small. We are using LLVM libObject library to read from object
55 files, so it is not completely a fair comparison, but as of February53 files, so it is not a completely fair comparison, but as of February
56 2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold54 2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
57 consists of 198k lines of C++ code.55 consists of 198k lines of C++ code.
5856
...@@ -102,8 +100,8 @@ under ``tools`` directory just like you probably did for clang. For the...@@ -102,8 +100,8 @@ under ``tools`` directory just like you probably did for clang. For the
102details, see `Getting Started with the LLVM System100details, see `Getting Started with the LLVM System
103<http://llvm.org/docs/GettingStarted.html>`_.101<http://llvm.org/docs/GettingStarted.html>`_.
104102
105If you haven't checkout out LLVM, the easiest way to build LLD is to103If you haven't checked out LLVM, the easiest way to build LLD is to
106checkout the entire LLVM projects/sub-projects from a git mirror and104check out the entire LLVM projects/sub-projects from a git mirror and
107build that tree. You need `cmake` and of course a C++ compiler.105build that tree. You need `cmake` and of course a C++ compiler.
108106
109.. code-block:: console107.. code-block:: console
...@@ -175,4 +173,5 @@ document soon....@@ -175,4 +173,5 @@ document soon.
175 AtomLLD173 AtomLLD
176 WebAssembly174 WebAssembly
177 windows_support175 windows_support
176 missingkeyfunction
178 ReleaseNotes177 ReleaseNotes
deps/lld/docs/ld.lld.1+53-4
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
3.\"3.\"
4.\" This man page documents only lld's ELF linking support, obtained originally4.\" This man page documents only lld's ELF linking support, obtained originally
5.\" from FreeBSD.5.\" from FreeBSD.
6.Dd July 30, 20186.Dd September 26, 2018
7.Dt LD.LLD 17.Dt LD.LLD 1
8.Os8.Os
9.Sh NAME9.Sh NAME
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13.Nm ld.lld13.Nm ld.lld
14.Op Ar options14.Op Ar options
15.Ar objfile ...15.Ar objfile ...
16
16.Sh DESCRIPTION17.Sh DESCRIPTION
17A linker takes one or more object, archive, and library files, and combines18A linker takes one or more object, archive, and library files, and combines
18them into an output file (an executable, a shared library, or another object19them into an output file (an executable, a shared library, or another object
...@@ -25,7 +26,21 @@ is a drop-in replacement for the GNU BFD and gold linkers....@@ -25,7 +26,21 @@ is a drop-in replacement for the GNU BFD and gold linkers.
25It accepts most of the same command line arguments and linker scripts26It accepts most of the same command line arguments and linker scripts
26as GNU linkers.27as GNU linkers.
27.Pp28.Pp
28These options are available:29.Nm
30currently supports i386, x86-64, ARM, AArch64, PowerPC32, PowerPC64,
31MIPS32, MIPS64, RISC-V, AMDGPU, Hexagon and SPARC V9 targets.
32.Nm
33acts as a Microsoft link.exe-compatible linker if invoked as
34.Nm lld-link
35and as macOS's ld if invoked as
36.Nm ld.ld64.
37All these targets are always supported however
38.Nm
39was built, so you can always use
40.Nm
41as a native linker as well as a cross linker.
42
43.Sh OPTIONS
29.Bl -tag -width indent44.Bl -tag -width indent
30.It Fl -allow-multiple-definition45.It Fl -allow-multiple-definition
31Do not error if a symbol is defined multiple times.46Do not error if a symbol is defined multiple times.
...@@ -144,6 +159,9 @@ Maximum number of errors to emit before stopping....@@ -144,6 +159,9 @@ Maximum number of errors to emit before stopping.
144A value of zero indicates that there is no limit.159A value of zero indicates that there is no limit.
145.It Fl -error-unresolved-symbols160.It Fl -error-unresolved-symbols
146Report unresolved symbols as errors.161Report unresolved symbols as errors.
162.It Fl -execute-only
163Mark executable sections unreadable. This option is currently only
164supported on AArch64.
147.It Fl -exclude-libs Ns = Ns Ar value165.It Fl -exclude-libs Ns = Ns Ar value
148Exclude static libraries from automatic export.166Exclude static libraries from automatic export.
149.It Fl -export-dynamic , Fl E167.It Fl -export-dynamic , Fl E
...@@ -293,10 +311,14 @@ Write optimization remarks in YAML format to...@@ -293,10 +311,14 @@ Write optimization remarks in YAML format to
293.Ar file .311.Ar file .
294.It Fl -opt-remarks-with-hotness312.It Fl -opt-remarks-with-hotness
295Include hotness information in the optimization remarks file.313Include hotness information in the optimization remarks file.
314.It Fl -pic-veneer
315Always generate position independent thunks.
296.It Fl -pie316.It Fl -pie
297Create a position independent executable.317Create a position independent executable.
298.It Fl -print-gc-sections318.It Fl -print-gc-sections
299List removed unused sections.319List removed unused sections.
320.It Fl -print-icf-sections
321List identical folded sections.
300.It Fl -print-map322.It Fl -print-map
301Print a link map to the standard output.323Print a link map to the standard output.
302.It Fl -push-state324.It Fl -push-state
...@@ -304,7 +326,7 @@ Save the current state of...@@ -304,7 +326,7 @@ Save the current state of
304.Fl -as-needed ,326.Fl -as-needed ,
305.Fl -static ,327.Fl -static ,
306and328and
307.Fl -while-archive.329.Fl -whole-archive.
308.It Fl -pop-state330.It Fl -pop-state
309Undo the effect of331Undo the effect of
310.Fl -push-state.332.Fl -push-state.
...@@ -426,6 +448,17 @@ This can be used to ensure linker invocation remains compatible with...@@ -426,6 +448,17 @@ This can be used to ensure linker invocation remains compatible with
426traditional Unix-like linkers.448traditional Unix-like linkers.
427.It Fl -warn-common449.It Fl -warn-common
428Warn about duplicate common symbols.450Warn about duplicate common symbols.
451.It Fl -warn-ifunc-textrel
452Warn about using ifunc symbols in conjunction with text relocations.
453Older versions of glibc library (2.28 and earlier) has a bug that causes
454the segment that includes ifunc symbols to be marked as not executable when
455they are relocated. As a result, although the program compiles and links
456successfully, it gives segmentation fault when the instruction pointer reaches
457an ifunc symbol. Use -warn-ifunc-textrel to let lld give a warning, if the
458code may include ifunc symbols, may do text relocations and be linked with
459an older glibc version. Otherwise, there is no need to use it, as the default
460value does not give a warning. This flag has been introduced in late 2018,
461has no counter part in ld and gold linkers, and may be removed in the future.
429.It Fl -warn-unresolved-symbols462.It Fl -warn-unresolved-symbols
430Report unresolved symbols as warnings.463Report unresolved symbols as warnings.
431.It Fl -whole-archive464.It Fl -whole-archive
...@@ -440,10 +473,22 @@ Make the main stack executable....@@ -440,10 +473,22 @@ Make the main stack executable.
440Stack permissions are recorded in the473Stack permissions are recorded in the
441.Dv PT_GNU_STACK474.Dv PT_GNU_STACK
442segment.475segment.
476.It Cm global
477Sets the
478.Dv DF_1_GLOBAL flag in the
479.Dv DYNAMIC
480section.
481Different loaders can decide how to handle this flag on their own.
443.It Cm initfirst482.It Cm initfirst
444Sets the483Sets the
445.Dv DF_1_INITFIRST484.Dv DF_1_INITFIRST
446flag to indicate the module should be initialized first.485flag to indicate the module should be initialized first.
486.It Cm interpose
487Set the
488.Dv DF_1_INTERPOSE
489flag to indicate to the runtime linker that the object is an interposer.
490During symbol resolution interposers are searched after the application
491but before other dependencies.
447.It Cm muldefs492.It Cm muldefs
448Do not error if a symbol is defined multiple times.493Do not error if a symbol is defined multiple times.
449The first definition will be used.494The first definition will be used.
...@@ -453,6 +498,10 @@ This is a synonym for...@@ -453,6 +498,10 @@ This is a synonym for
453Disable combining and sorting multiple relocation sections.498Disable combining and sorting multiple relocation sections.
454.It Cm nocopyreloc499.It Cm nocopyreloc
455Disable the creation of copy relocations.500Disable the creation of copy relocations.
501.It Cm nodefaultlib
502Set the
503.Dv DF_1_NODEFLIB
504flag to indicate that default library search paths should be ignored.
456.It Cm nodelete505.It Cm nodelete
457Set the506Set the
458.Dv DF_1_NODELETE507.Dv DF_1_NODELETE
...@@ -460,7 +509,7 @@ flag to indicate that the object cannot be unloaded from a process....@@ -460,7 +509,7 @@ flag to indicate that the object cannot be unloaded from a process.
460.It Cm nodlopen509.It Cm nodlopen
461Set the510Set the
462.Dv DF_1_NOOPEN511.Dv DF_1_NOOPEN
463flag to indcate that the object may not be opened by512flag to indicate that the object may not be opened by
464.Xr dlopen 3 .513.Xr dlopen 3 .
465.It Cm norelro514.It Cm norelro
466Do not indicate that portions of the object shold be mapped read-only515Do not indicate that portions of the object shold be mapped read-only
deps/lld/docs/missingkeyfunction.rst created+84
...@@ -0,0 +1,84 @@
1Missing Key Function
2====================
3
4If your build failed with a linker error something like this::
5
6 foo.cc:28: error: undefined reference to 'vtable for C'
7 the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
8
9it's likely that your class C has a key function (defined by the ABI as the first
10non-pure, non-inline, virtual method), but you haven't actually defined it.
11
12When a class has a key function, the compiler emits the vtable (and some other
13things as well) only in the translation unit that defines that key function. Thus,
14if you're missing the key function, you'll also be missing the vtable. If no other
15function calls your missing method, you won't see any undefined reference errors
16for it, but you will see undefined references to the vtable symbol.
17
18When a class has no non-pure, non-inline, virtual methods, there is no key
19method, and the compiler is forced to emit the vtable in every translation unit
20that references the class. In this case, it is emitted in a COMDAT section,
21which allows the linker to eliminate all duplicate copies. This is still
22wasteful in terms of object file size and link time, so it's always advisable to
23ensure there is at least one eligible method that can serve as the key function.
24
25Here are the most common mistakes that lead to this error:
26
27Failing to define a virtual destructor
28--------------------------------------
29
30Say you have a base class declared in a header file::
31
32 class B {
33 public:
34 B();
35 virtual ~B();
36 ...
37 };
38
39Here, ``~B`` is the first non-pure, non-inline, virtual method, so it is the key
40method. If you forget to define ``B::~B`` in your source file, the compiler will
41not emit the vtable for ``B``, and you'll get an undefined reference to "vtable
42for B".
43
44This is just an example of the more general mistake of forgetting to define the
45key function, but it's quite common because virtual destructors are likely to be
46the first eligible key function and it's easy to forget to implement them. It's
47also more likely that you won't have any direct references to the destructor, so
48you won't see any undefined reference errors that point directly to the problem.
49
50The solution in this case is to implement the missing method.
51
52Forgetting to declare a virtual method in an abstract class as pure
53-------------------------------------------------------------------
54
55Say you have an abstract base class declared in a header file::
56
57 class A {
58 public:
59 A();
60 virtual ~A() {}
61 virtual int foo() = 0;
62 ...
63 virtual int bar();
64 ...
65 };
66
67This base class is intended to be abstract, but you forgot to mark one of the
68methods pure. Here, ``A::bar``, being non-pure, is nominated as the key function,
69and as a result, the vtable for ``A`` is not emitted, because the compiler is
70waiting for a translation unit that defines ``A::bar``.
71
72The solution in this case is to add the missing ``= 0`` to the declaration of
73``A::bar``.
74
75Key method is defined, but the linker doesn't see it
76----------------------------------------------------
77
78It's also possible that you have defined the key function somewhere, but the
79object file containing the definition of that method isn't being linked into
80your application.
81
82The solution in this case is to check your dependencies to make sure that
83the object file or the library file containing the key function is given to
84the linker.
deps/lld/docs/open_projects.rst-2
...@@ -3,8 +3,6 @@...@@ -3,8 +3,6 @@
3Open Projects3Open Projects
4=============4=============
55
6.. include:: ../include/lld/Core/TODO.txt
7
8Documentation TODOs6Documentation TODOs
9~~~~~~~~~~~~~~~~~~~7~~~~~~~~~~~~~~~~~~~
108
deps/lld/docs/windows_support.rst+2-2
...@@ -20,8 +20,8 @@ command line options, and it drives further linking processes. LLD accepts...@@ -20,8 +20,8 @@ command line options, and it drives further linking processes. LLD accepts
20almost all command line options that the linker shipped with Microsoft Visual20almost all command line options that the linker shipped with Microsoft Visual
21C++ (link.exe) supports.21C++ (link.exe) supports.
2222
23The current status is that LLD can link itself on Windows x86/x6423The current status is that LLD is used to link production builds of large
24using Visual C++ 2013 as the compiler.24real-world binaries such as Firefox and Chromium.
2525
26Development status26Development status
27==================27==================
deps/lld/include/lld/Common/Args.h+3
...@@ -29,6 +29,9 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,...@@ -29,6 +29,9 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
29 uint64_t Default);29 uint64_t Default);
3030
31std::vector<StringRef> getLines(MemoryBufferRef MB);31std::vector<StringRef> getLines(MemoryBufferRef MB);
32
33StringRef getFilenameWithoutExe(StringRef Path);
34
32} // namespace args35} // namespace args
33} // namespace lld36} // namespace lld
3437
deps/lld/include/lld/Common/ErrorHandler.h+1-1
...@@ -153,7 +153,7 @@ T check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {...@@ -153,7 +153,7 @@ T check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {
153inline std::string toString(const Twine &S) { return S.str(); }153inline std::string toString(const Twine &S) { return S.str(); }
154154
155// To evaluate the second argument lazily, we use C macro.155// To evaluate the second argument lazily, we use C macro.
156#define CHECK(E, S) check2(E, [&] { return toString(S); })156#define CHECK(E, S) check2((E), [&] { return toString(S); })
157157
158} // namespace lld158} // namespace lld
159159
deps/lld/include/lld/Common/LLVM.h+58-42
...@@ -22,53 +22,69 @@...@@ -22,53 +22,69 @@
22#include <utility>22#include <utility>
2323
24namespace llvm {24namespace llvm {
25 // ADT's.25// ADT's.
26 class Error;26class raw_ostream;
27 class StringRef;27class Error;
28 class Twine;28class StringRef;
29 class MemoryBuffer;29class Twine;
30 class MemoryBufferRef;30class MemoryBuffer;
31 template<typename T> class ArrayRef;31class MemoryBufferRef;
32 template<unsigned InternalLen> class SmallString;32template <typename T> class ArrayRef;
33 template<typename T, unsigned N> class SmallVector;33template <unsigned InternalLen> class SmallString;
34 template<typename T> class SmallVectorImpl;34template <typename T, unsigned N> class SmallVector;
35template <typename T> class ErrorOr;
36template <typename T> class Expected;
3537
36 template<typename T>38namespace object {
37 struct SaveAndRestore;39class WasmObjectFile;
40struct WasmSection;
41struct WasmSegment;
42class WasmSymbol;
43} // namespace object
3844
39 template<typename T>45namespace wasm {
40 class ErrorOr;46struct WasmEvent;
4147struct WasmEventType;
42 template<typename T>48struct WasmFunction;
43 class Expected;49struct WasmGlobal;
4450struct WasmGlobalType;
45 class raw_ostream;51struct WasmRelocation;
46 // TODO: DenseMap, ...52struct WasmSignature;
47}53} // namespace wasm
54} // namespace llvm
4855
49namespace lld {56namespace lld {
50 // Casting operators.57// Casting operators.
51 using llvm::isa;58using llvm::cast;
52 using llvm::cast;59using llvm::cast_or_null;
53 using llvm::dyn_cast;60using llvm::dyn_cast;
54 using llvm::dyn_cast_or_null;61using llvm::dyn_cast_or_null;
55 using llvm::cast_or_null;62using llvm::isa;
5663
57 // ADT's.64// ADT's.
58 using llvm::Error;65using llvm::ArrayRef;
59 using llvm::StringRef;66using llvm::Error;
60 using llvm::Twine;67using llvm::ErrorOr;
61 using llvm::MemoryBuffer;68using llvm::Expected;
62 using llvm::MemoryBufferRef;69using llvm::MemoryBuffer;
63 using llvm::ArrayRef;70using llvm::MemoryBufferRef;
64 using llvm::SmallString;71using llvm::raw_ostream;
65 using llvm::SmallVector;72using llvm::SmallString;
66 using llvm::SmallVectorImpl;73using llvm::SmallVector;
67 using llvm::SaveAndRestore;74using llvm::StringRef;
68 using llvm::ErrorOr;75using llvm::Twine;
69 using llvm::Expected;
7076
71 using llvm::raw_ostream;77using llvm::object::WasmObjectFile;
78using llvm::object::WasmSection;
79using llvm::object::WasmSegment;
80using llvm::object::WasmSymbol;
81using llvm::wasm::WasmEvent;
82using llvm::wasm::WasmEventType;
83using llvm::wasm::WasmFunction;
84using llvm::wasm::WasmGlobal;
85using llvm::wasm::WasmGlobalType;
86using llvm::wasm::WasmRelocation;
87using llvm::wasm::WasmSignature;
72} // end namespace lld.88} // end namespace lld.
7389
74namespace std {90namespace std {
...@@ -78,6 +94,6 @@ public:...@@ -78,6 +94,6 @@ public:
78 return llvm::hash_value(s);94 return llvm::hash_value(s);
79 }95 }
80};96};
81}97} // namespace std
8298
83#endif99#endif
deps/lld/include/lld/Common/Strings.h-3
...@@ -41,9 +41,6 @@ private:...@@ -41,9 +41,6 @@ private:
41 std::vector<llvm::GlobPattern> Patterns;41 std::vector<llvm::GlobPattern> Patterns;
42};42};
4343
44inline llvm::ArrayRef<uint8_t> toArrayRef(llvm::StringRef S) {
45 return {reinterpret_cast<const uint8_t *>(S.data()), S.size()};
46}
47} // namespace lld44} // namespace lld
4845
49#endif46#endif
deps/lld/include/lld/Common/TargetOptionsCommandFlags.h+1
...@@ -19,4 +19,5 @@ namespace lld {...@@ -19,4 +19,5 @@ namespace lld {
19llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();19llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
20llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();20llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();
21std::string GetCPUStr();21std::string GetCPUStr();
22std::vector<std::string> GetMAttrs();
22}23}
deps/lld/include/lld/Common/Threads.h+1-1
...@@ -74,7 +74,7 @@ template <typename R, class FuncTy> void parallelForEach(R &&Range, FuncTy Fn) {...@@ -74,7 +74,7 @@ template <typename R, class FuncTy> void parallelForEach(R &&Range, FuncTy Fn) {
74}74}
7575
76inline void parallelForEachN(size_t Begin, size_t End,76inline void parallelForEachN(size_t Begin, size_t End,
77 std::function<void(size_t)> Fn) {77 llvm::function_ref<void(size_t)> Fn) {
78 if (ThreadsEnabled)78 if (ThreadsEnabled)
79 for_each_n(llvm::parallel::par, Begin, End, Fn);79 for_each_n(llvm::parallel::par, Begin, End, Fn);
80 else80 else
deps/lld/include/lld/Core/TODO.txt deleted-14
...@@ -1,14 +0,0 @@
1include/lld/Core
2~~~~~~~~~~~~~~~~
3
4* The yaml reader/writer interfaces should be changed to return
5 an explanatory string if there is an error. The existing error_code
6 abstraction only works for returning low level OS errors. It does not
7 work for describing formatting issues.
8
9* We need to add more attributes to File. In particular, we need cpu
10 and OS information (like target triples). We should also provide explicit
11 support for `LLVM IR module flags metadata`__.
12
13.. __: http://llvm.org/docs/LangRef.html#module_flags
14.. _Clang: http://clang.llvm.org/docs/InternalsManual.html#Diagnostics
deps/lld/lib/Driver/DarwinLdDriver.cpp+7-4
...@@ -382,10 +382,13 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx) {...@@ -382,10 +382,13 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx) {
382 if (arch == MachOLinkingContext::arch_unknown &&382 if (arch == MachOLinkingContext::arch_unknown &&
383 !parsedArgs.getLastArg(OPT_test_file_usage)) {383 !parsedArgs.getLastArg(OPT_test_file_usage)) {
384 // If no -arch and no options at all, print usage message.384 // If no -arch and no options at all, print usage message.
385 if (parsedArgs.size() == 0)385 if (parsedArgs.size() == 0) {
386 table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);386 table.PrintHelp(llvm::outs(),
387 else387 (std::string(args[0]) + " [options] file...").c_str(),
388 "LLVM Linker", false);
389 } else {
388 error("-arch not specified and could not be inferred");390 error("-arch not specified and could not be inferred");
391 }
389 return false;392 return false;
390 }393 }
391 }394 }
...@@ -1143,7 +1146,7 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) {...@@ -1143,7 +1146,7 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) {
1143/// This is where the link is actually performed.1146/// This is where the link is actually performed.
1144bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,1147bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
1145 raw_ostream &Error) {1148 raw_ostream &Error) {
1146 errorHandler().LogName = llvm::sys::path::filename(args[0]);1149 errorHandler().LogName = args::getFilenameWithoutExe(args[0]);
1147 errorHandler().ErrorLimitExceededMsg =1150 errorHandler().ErrorLimitExceededMsg =
1148 "too many errors emitted, stopping now (use "1151 "too many errors emitted, stopping now (use "
1149 "'-error-limit 0' to see all errors)";1152 "'-error-limit 0' to see all errors)";
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+2
...@@ -80,6 +80,7 @@ public:...@@ -80,6 +80,7 @@ public:
80 switch (ref->kindValue()) {80 switch (ref->kindValue()) {
81 case ripRel32Got:81 case ripRel32Got:
82 assert(targetNowGOT && "target must be GOT");82 assert(targetNowGOT && "target must be GOT");
83 LLVM_FALLTHROUGH;
83 case ripRel32GotLoad:84 case ripRel32GotLoad:
84 const_cast<Reference *>(ref)85 const_cast<Reference *>(ref)
85 ->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);86 ->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);
...@@ -621,6 +622,7 @@ void ArchHandler_x86_64::applyFixupFinal(...@@ -621,6 +622,7 @@ void ArchHandler_x86_64::applyFixupFinal(
621 // Fall into llvm_unreachable().622 // Fall into llvm_unreachable().
622 break;623 break;
623 }624 }
625 llvm_unreachable("invalid x86_64 Reference Kind");
624}626}
625627
626void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,628void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp+1
...@@ -262,6 +262,7 @@ void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,...@@ -262,6 +262,7 @@ void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
262 case llvm::MachO::MH_OBJECT:262 case llvm::MachO::MH_OBJECT:
263 _printRemainingUndefines = false;263 _printRemainingUndefines = false;
264 _allowRemainingUndefines = true;264 _allowRemainingUndefines = true;
265 break;
265 default:266 default:
266 break;267 break;
267 }268 }
deps/lld/test/CMakeLists.txt+3
...@@ -53,6 +53,9 @@ add_lit_testsuite(check-lld "Running lld test suite"...@@ -53,6 +53,9 @@ add_lit_testsuite(check-lld "Running lld test suite"
53 DEPENDS ${LLD_TEST_DEPS}53 DEPENDS ${LLD_TEST_DEPS}
54 )54 )
5555
56add_custom_target(lld-test-depends DEPENDS ${LLD_TEST_DEPS})
57set_target_properties(lld-test-depends PROPERTIES FOLDER "lld tests")
58
56add_lit_testsuites(LLD ${CMAKE_CURRENT_SOURCE_DIR}59add_lit_testsuites(LLD ${CMAKE_CURRENT_SOURCE_DIR}
57 PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg60 PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
58 lld_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg61 lld_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
deps/lld/test/COFF/Inputs/bad-block-size.pdb created+2
...@@ -0,0 +1,2 @@
1Microsoft C/C++ MSF 7.00
2DS
\ No newline at end of file
deps/lld/test/COFF/Inputs/comdat-jumptable2.s created+35
...@@ -0,0 +1,35 @@
1 .section .text@comdatfunc, "x"
2 .linkonce discard
3 .globl comdatfunc
4comdatfunc:
5 leaq .Ljumptable(%rip), %rax
6 movslq (%rax, %rcx, 4), %rcx
7 addq %rcx, %rax
8 jmp *%rax
9
10 .section .rdata, "dr"
11 .long 0xcccccccc
12.Ljumptable:
13 .long .Ltail1-.Ljumptable
14 .long .Ltail2-.Ljumptable
15 .long .Ltail3-.Ljumptable
16 .long 0xdddddddd
17
18 .section .text@comdatfunc, "x"
19# If assembled with binutils, the following line can be kept in:
20# .linkonce discard
21.Ltail1:
22 movl $1, %eax
23 ret
24.Ltail2:
25 movl $2, %eax
26 ret
27.Ltail3:
28 movl $3, %eax
29 ret
30
31 .text
32 .globl otherfunc
33otherfunc:
34 call comdatfunc
35 ret
deps/lld/test/COFF/Inputs/crt-dyn-initializer-order_1.yaml created+15
...@@ -0,0 +1,15 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: '.CRT$XCU'
7 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
8 Alignment: 1
9 SectionData: 55
10 - Name: '.CRT$XCU'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 SectionData: 70
14symbols:
15...
deps/lld/test/COFF/Inputs/crt-dyn-initializer-order_2.yaml created+19
...@@ -0,0 +1,19 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: '.CRT$XCU'
7 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
8 Alignment: 1
9 SectionData: 10
10 - Name: '.CRT$XCU'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 SectionData: 11
14 - Name: '.CRT$XCU'
15 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
16 Alignment: 1
17 SectionData: 12
18symbols:
19...
deps/lld/test/COFF/Inputs/empty.yaml created+67
...@@ -0,0 +1,67 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_I386
4 Characteristics: [ ]
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: 31C0C3
10 - Name: .data
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
12 Alignment: 4
13 SectionData: ''
14 - Name: .bss
15 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
16 Alignment: 4
17 SectionData: ''
18symbols:
19 - Name: .text
20 Value: 0
21 SectionNumber: 1
22 SimpleType: IMAGE_SYM_TYPE_NULL
23 ComplexType: IMAGE_SYM_DTYPE_NULL
24 StorageClass: IMAGE_SYM_CLASS_STATIC
25 SectionDefinition:
26 Length: 3
27 NumberOfRelocations: 0
28 NumberOfLinenumbers: 0
29 CheckSum: 3963538403
30 Number: 1
31 - Name: .data
32 Value: 0
33 SectionNumber: 2
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_NULL
36 StorageClass: IMAGE_SYM_CLASS_STATIC
37 SectionDefinition:
38 Length: 0
39 NumberOfRelocations: 0
40 NumberOfLinenumbers: 0
41 CheckSum: 0
42 Number: 2
43 - Name: .bss
44 Value: 0
45 SectionNumber: 3
46 SimpleType: IMAGE_SYM_TYPE_NULL
47 ComplexType: IMAGE_SYM_DTYPE_NULL
48 StorageClass: IMAGE_SYM_CLASS_STATIC
49 SectionDefinition:
50 Length: 0
51 NumberOfRelocations: 0
52 NumberOfLinenumbers: 0
53 CheckSum: 0
54 Number: 3
55 - Name: '@feat.00'
56 Value: 1
57 SectionNumber: -1
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_NULL
60 StorageClass: IMAGE_SYM_CLASS_STATIC
61 - Name: _main
62 Value: 0
63 SectionNumber: 1
64 SimpleType: IMAGE_SYM_TYPE_NULL
65 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
66 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
67...
deps/lld/test/COFF/Inputs/far-arm-thumb-abs.s deleted-2
...@@ -1,2 +0,0 @@
1.global too_far1
2too_far1 = 0x1401004
deps/lld/test/COFF/Inputs/far-arm-thumb-abs20.s deleted-2
...@@ -1,2 +0,0 @@
1.global too_far20
2too_far20 = 0x501004
deps/lld/test/COFF/Inputs/gnu-implib-data.s created+23
...@@ -0,0 +1,23 @@
1 .global __imp_data
2
3 # The data that is emitted into .idata$7 here is isn't needed for
4 # the import data structures, but we need to emit something which
5 # produces a relocation against _head_test_lib, to pull in the
6 # header and trailer objects.
7
8 .section .idata$7
9 .rva _head_test_lib
10
11 .section .idata$5
12__imp_data:
13 .rva .Lhint_name
14 .long 0
15
16 .section .idata$4
17 .rva .Lhint_name
18 .long 0
19
20 .section .idata$6
21.Lhint_name:
22 .short 0
23 .asciz "data"
deps/lld/test/COFF/Inputs/gnu-implib-func.s created+27
...@@ -0,0 +1,27 @@
1 .text
2 .global func
3 .global __imp_func
4func:
5 jmp *__imp_func
6
7 # The data that is emitted into .idata$7 here is isn't needed for
8 # the import data structures, but we need to emit something which
9 # produces a relocation against _head_test_lib, to pull in the
10 # header and trailer objects.
11
12 .section .idata$7
13 .rva _head_test_lib
14
15 .section .idata$5
16__imp_func:
17 .rva .Lhint_name
18 .long 0
19
20 .section .idata$4
21 .rva .Lhint_name
22 .long 0
23
24 .section .idata$6
25.Lhint_name:
26 .short 0
27 .asciz "func"
deps/lld/test/COFF/Inputs/gnu-implib-head.s created+13
...@@ -0,0 +1,13 @@
1 .section .idata$2
2 .global _head_test_lib
3_head_test_lib:
4 .rva hname
5 .long 0
6 .long 0
7 .rva __test_lib_iname
8 .rva fthunk
9
10 .section .idata$5
11fthunk:
12 .section .idata$4
13hname:
deps/lld/test/COFF/Inputs/gnu-implib-tail.s created+11
...@@ -0,0 +1,11 @@
1 .section .idata$4
2 .long 0
3 .long 0
4 .section .idata$5
5 .long 0
6 .long 0
7
8 .section .idata$7
9 .global __test_lib_iname
10__test_lib_iname:
11 .asciz "foo.dll"
deps/lld/test/COFF/Inputs/gnu-weak.o created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/gnu-weak.o differ
deps/lld/test/COFF/Inputs/gnu-weak2.o created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/gnu-weak2.o differ
deps/lld/test/COFF/Inputs/icf-safe.s created+9
...@@ -0,0 +1,9 @@
1.section .rdata,"dr",one_only,non_addrsig1
2.globl non_addrsig1
3non_addrsig1:
4.byte 3
5
6.section .rdata,"dr",one_only,non_addrsig2
7.globl non_addrsig2
8non_addrsig2:
9.byte 3
deps/lld/test/COFF/Inputs/inline-weak.o created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/inline-weak.o differ
deps/lld/test/COFF/Inputs/inline-weak2.o created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/inline-weak2.o differ
deps/lld/test/COFF/Inputs/pdb-file-statics-a.yaml+3-3
...@@ -1353,7 +1353,7 @@ sections:...@@ -1353,7 +1353,7 @@ sections:
1353 RegRelativeSym:1353 RegRelativeSym:
1354 Offset: 481354 Offset: 48
1355 Type: 1161355 Type: 116
1356 Register: CVRegRSP1356 Register: RSP
1357 VarName: __formal1357 VarName: __formal
1358 - Kind: S_PROC_ID_END1358 - Kind: S_PROC_ID_END
1359 ScopeEndSym:1359 ScopeEndSym:
...@@ -1528,13 +1528,13 @@ sections:...@@ -1528,13 +1528,13 @@ sections:
1528 RegRelativeSym:1528 RegRelativeSym:
1529 Offset: 481529 Offset: 48
1530 Type: 1161530 Type: 116
1531 Register: CVRegRSP1531 Register: RSP
1532 VarName: argc1532 VarName: argc
1533 - Kind: S_REGREL321533 - Kind: S_REGREL32
1534 RegRelativeSym:1534 RegRelativeSym:
1535 Offset: 561535 Offset: 56
1536 Type: 40981536 Type: 4098
1537 Register: CVRegRSP1537 Register: RSP
1538 VarName: argv1538 VarName: argv
1539 - Kind: S_PROC_ID_END1539 - Kind: S_PROC_ID_END
1540 ScopeEndSym:1540 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-file-statics-b.yaml+1-1
...@@ -1328,7 +1328,7 @@ sections:...@@ -1328,7 +1328,7 @@ sections:
1328 RegRelativeSym:1328 RegRelativeSym:
1329 Offset: 481329 Offset: 48
1330 Type: 1161330 Type: 116
1331 Register: CVRegRSP1331 Register: RSP
1332 VarName: __formal1332 VarName: __formal
1333 - Kind: S_PROC_ID_END1333 - Kind: S_PROC_ID_END
1334 ScopeEndSym:1334 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-scopes-a.yaml+4-4
...@@ -53,7 +53,7 @@ sections:...@@ -53,7 +53,7 @@ sections:
53 RegRelativeSym:53 RegRelativeSym:
54 Offset: 854 Offset: 8
55 Type: 11655 Type: 116
56 Register: CVRegRSP56 Register: RSP
57 VarName: x57 VarName: x
58 - Kind: S_PROC_ID_END58 - Kind: S_PROC_ID_END
59 ScopeEndSym:59 ScopeEndSym:
...@@ -93,7 +93,7 @@ sections:...@@ -93,7 +93,7 @@ sections:
93 RegRelativeSym:93 RegRelativeSym:
94 Offset: 6494 Offset: 64
95 Type: 11695 Type: 116
96 Register: CVRegRSP96 Register: RSP
97 VarName: argc97 VarName: argc
98 - Kind: S_BLOCK3298 - Kind: S_BLOCK32
99 BlockSym:99 BlockSym:
...@@ -104,7 +104,7 @@ sections:...@@ -104,7 +104,7 @@ sections:
104 RegRelativeSym:104 RegRelativeSym:
105 Offset: 32105 Offset: 32
106 Type: 116106 Type: 116
107 Register: CVRegRSP107 Register: RSP
108 VarName: x108 VarName: x
109 - Kind: S_END109 - Kind: S_END
110 ScopeEndSym:110 ScopeEndSym:
...@@ -117,7 +117,7 @@ sections:...@@ -117,7 +117,7 @@ sections:
117 RegRelativeSym:117 RegRelativeSym:
118 Offset: 36118 Offset: 36
119 Type: 116119 Type: 116
120 Register: CVRegRSP120 Register: RSP
121 VarName: y121 VarName: y
122 - Kind: S_END122 - Kind: S_END
123 ScopeEndSym:123 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-scopes-b.yaml+3-3
...@@ -53,7 +53,7 @@ sections:...@@ -53,7 +53,7 @@ sections:
53 RegRelativeSym:53 RegRelativeSym:
54 Offset: 6454 Offset: 64
55 Type: 11655 Type: 116
56 Register: CVRegRSP56 Register: RSP
57 VarName: x57 VarName: x
58 - Kind: S_BLOCK3258 - Kind: S_BLOCK32
59 BlockSym:59 BlockSym:
...@@ -64,7 +64,7 @@ sections:...@@ -64,7 +64,7 @@ sections:
64 RegRelativeSym:64 RegRelativeSym:
65 Offset: 3265 Offset: 32
66 Type: 11666 Type: 116
67 Register: CVRegRSP67 Register: RSP
68 VarName: y68 VarName: y
69 - Kind: S_END69 - Kind: S_END
70 ScopeEndSym:70 ScopeEndSym:
...@@ -77,7 +77,7 @@ sections:...@@ -77,7 +77,7 @@ sections:
77 RegRelativeSym:77 RegRelativeSym:
78 Offset: 3678 Offset: 36
79 Type: 11679 Type: 116
80 Register: CVRegRSP80 Register: RSP
81 VarName: w81 VarName: w
82 - Kind: S_END82 - Kind: S_END
83 ScopeEndSym:83 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-type-server-missing-2.yaml created+32
...@@ -0,0 +1,32 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: '.debug$T'
7 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
8 Alignment: 1
9 Types:
10 - Kind: LF_TYPESERVER2
11 TypeServer2:
12 Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
13 Age: 18
14 Name: 'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb'
15 - Name: '.text$mn'
16 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
17 Alignment: 16
18 SectionData: 33C0C3
19symbols:
20 - Name: '.debug$T'
21 Value: 0
22 SectionNumber: 2
23 SimpleType: IMAGE_SYM_TYPE_NULL
24 ComplexType: IMAGE_SYM_DTYPE_NULL
25 StorageClass: IMAGE_SYM_CLASS_STATIC
26 SectionDefinition:
27 Length: 564
28 NumberOfRelocations: 0
29 NumberOfLinenumbers: 0
30 CheckSum: 0
31 Number: 0
32...
deps/lld/test/COFF/Inputs/pdb-type-server-simple-a.yaml+1-1
...@@ -53,7 +53,7 @@ sections:...@@ -53,7 +53,7 @@ sections:
53 RegRelativeSym:53 RegRelativeSym:
54 Offset: 3254 Offset: 32
55 Type: 410255 Type: 4102
56 Register: CVRegRSP56 Register: RSP
57 VarName: f57 VarName: f
58 - Kind: S_PROC_ID_END58 - Kind: S_PROC_ID_END
59 ScopeEndSym:59 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-type-server-simple-b.yaml+1-1
...@@ -53,7 +53,7 @@ sections:...@@ -53,7 +53,7 @@ sections:
53 RegRelativeSym:53 RegRelativeSym:
54 Offset: 854 Offset: 8
55 Type: 409755 Type: 4097
56 Register: CVRegRSP56 Register: RSP
57 VarName: p57 VarName: p
58 - Kind: S_PROC_ID_END58 - Kind: S_PROC_ID_END
59 ScopeEndSym:59 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-type-server-valid-signature.yaml created+121
...@@ -0,0 +1,121 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: '.debug$S'
7 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
8 Alignment: 1
9 Subsections:
10 - !Symbols
11 Records:
12 - Kind: S_GPROC32_ID
13 ProcSym:
14 CodeSize: 3
15 DbgStart: 0
16 DbgEnd: 2
17 FunctionType: 4199
18 Flags: [ ]
19 DisplayName: main
20 - Kind: S_FRAMEPROC
21 FrameProcSym:
22 TotalFrameBytes: 0
23 PaddingFrameBytes: 0
24 OffsetToPadding: 0
25 BytesOfCalleeSavedRegisters: 0
26 OffsetOfExceptionHandler: 0
27 SectionIdOfExceptionHandler: 0
28 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
29 - Kind: S_PROC_ID_END
30 ScopeEndSym:
31 - !Lines
32 CodeSize: 3
33 Flags: [ ]
34 RelocOffset: 0
35 RelocSegment: 0
36 Blocks:
37 - FileName: 'c:\src\llvm-project\build\t.c'
38 Lines:
39 - Offset: 0
40 LineStart: 1
41 IsStatement: true
42 EndDelta: 0
43 Columns:
44 - !FileChecksums
45 Checksums:
46 - FileName: 'c:\src\llvm-project\build\t.c'
47 Kind: MD5
48 Checksum: 270A878DCC1B845655B162F56C4F5020
49 - !StringTable
50 Strings:
51 - 'c:\src\llvm-project\build\t.c'
52 Relocations:
53 - VirtualAddress: 44
54 SymbolName: main
55 Type: IMAGE_REL_AMD64_SECREL
56 - VirtualAddress: 48
57 SymbolName: main
58 Type: IMAGE_REL_AMD64_SECTION
59 - VirtualAddress: 100
60 SymbolName: main
61 Type: IMAGE_REL_AMD64_SECREL
62 - VirtualAddress: 104
63 SymbolName: main
64 Type: IMAGE_REL_AMD64_SECTION
65 - Name: '.debug$T'
66 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
67 Alignment: 1
68 Types:
69 - Kind: LF_TYPESERVER2
70 TypeServer2:
71 Guid: '{8DABD2A0-28FF-CB43-9BAF-175B77B76414}'
72 Age: 18
73 Name: 'pdb-diff-cl.pdb'
74 - Name: '.text$mn'
75 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
76 Alignment: 16
77 SectionData: 33C0C3
78symbols:
79 - Name: '.debug$S'
80 Value: 0
81 SectionNumber: 1
82 SimpleType: IMAGE_SYM_TYPE_NULL
83 ComplexType: IMAGE_SYM_DTYPE_NULL
84 StorageClass: IMAGE_SYM_CLASS_STATIC
85 SectionDefinition:
86 Length: 328
87 NumberOfRelocations: 4
88 NumberOfLinenumbers: 0
89 CheckSum: 0
90 Number: 0
91 - Name: '.debug$T'
92 Value: 0
93 SectionNumber: 2
94 SimpleType: IMAGE_SYM_TYPE_NULL
95 ComplexType: IMAGE_SYM_DTYPE_NULL
96 StorageClass: IMAGE_SYM_CLASS_STATIC
97 SectionDefinition:
98 Length: 564
99 NumberOfRelocations: 0
100 NumberOfLinenumbers: 0
101 CheckSum: 0
102 Number: 0
103 - Name: '.text$mn'
104 Value: 0
105 SectionNumber: 3
106 SimpleType: IMAGE_SYM_TYPE_NULL
107 ComplexType: IMAGE_SYM_DTYPE_NULL
108 StorageClass: IMAGE_SYM_CLASS_STATIC
109 SectionDefinition:
110 Length: 3
111 NumberOfRelocations: 0
112 NumberOfLinenumbers: 0
113 CheckSum: 4021952397
114 Number: 0
115 - Name: main
116 Value: 0
117 SectionNumber: 3
118 SimpleType: IMAGE_SYM_TYPE_NULL
119 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
120 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
121...
deps/lld/test/COFF/Inputs/precomp-a.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/precomp-a.obj differ
deps/lld/test/COFF/Inputs/precomp-b.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/precomp-b.obj differ
deps/lld/test/COFF/Inputs/precomp-invalid.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/precomp-invalid.obj differ
deps/lld/test/COFF/Inputs/precomp.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/precomp.obj differ
deps/lld/test/COFF/arm-thumb-branch-error.s deleted-10
...@@ -1,10 +0,0 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs.s -o %tfar
3// RUN: not lld-link -entry:_start -subsystem:console %t %tfar -out:%t2 2>&1 | FileCheck %s
4// REQUIRES: arm
5 .syntax unified
6 .globl _start
7_start:
8 bl too_far1
9
10// CHECK: relocation out of range
deps/lld/test/COFF/arm-thumb-branch20-error.s+9-3
...@@ -1,10 +1,16 @@...@@ -1,10 +1,16 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t.obj2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t.obj
3// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs20.s -o %t.far.obj3// RUN: not lld-link -entry:_start -subsystem:console %t.obj -out:%t.exe 2>&1 | FileCheck %s
4// RUN: not lld-link -entry:_start -subsystem:console %t.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
5 .syntax unified4 .syntax unified
6 .globl _start5 .globl _start
7_start:6_start:
8 bne too_far207 bne too_far20
8 .space 0x100000
9 .section .text$a, "xr"
10too_far20:
11 bx lr
912
10// CHECK: relocation out of range13// When trying to add a thunk at the end of the section, the thunk itself
14// will be too far away, so this won't converge.
15
16// CHECK: adding thunks hasn't converged
deps/lld/test/COFF/arm-thumb-thunks-multipass.s created+70
...@@ -0,0 +1,70 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
4// RUN: llvm-objdump -d %t.exe -start-address=0x403000 -stop-address=0x403008 | FileCheck -check-prefix=FUNC01 %s
5// RUN: llvm-objdump -d %t.exe -start-address=0x404ffa -stop-address=0x405012 | FileCheck -check-prefix=FUNC01-THUNKS %s
6
7// VERBOSE: Added {{.*}} thunks with margin 204800 in 2 passes
8
9 .syntax unified
10 .globl main
11 .text
12main:
13 b func01
14 bx lr
15
16.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
17 .section .text$\i\()a, "xr"
18 .balign 8192
19func\i:
20 bne far_func\i
21 bne func_within_margin\i
22 // Originally, the first section is less than 8192 bytes large, and the
23 // second one follows almost directly. After adding one thunk after
24 // the first section, the second one will move forward by 8192 bytes
25 // due to the alignment.
26 .space 8192 - 8 - 4
27
28 .section .text$\i\()b, "xr"
29 .balign 8192
30align\i:
31 nop
32.endr
33
34 .section .text$999, "xr"
35tail:
36 .space 0x100000 - 100*1024 - 18*8192*2
37 // Initially, these symbols are within range from all the sections above,
38 // even when taking the initial margin into account. After adding thunks
39 // to all the sections above, some of these are also out of range, forcing
40 // running a second pass.
41.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
42func_within_margin\i:
43 nop
44.endr
45 .space 0x100000
46
47 // These are always out of range.
48.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
49far_func\i:
50 nop
51.endr
52 bx lr
53
54// FUNC01: 403000: 41 f0 fc 87 bne.w #8184 <.text+0x3ffc>
55// FUNC01: 403004: 41 f0 ff 87 bne.w #8190 <.text+0x4006>
56
57// Check that we only have two thunks here, even if we created the first
58// thunk twice (once in the first pass, then thrown away and recreated
59// in the second pass).
60
61// FUNC01-THUNKS: 404ffa: 00 00 movs r0, r0
62// The instruction above is padding from the .space
63// FUNC01-THUNKS: 404ffc: 47 f2 1e 0c movw r12, #28702
64// FUNC01-THUNKS: 405000: c0 f2 20 0c movt r12, #32
65// FUNC01-THUNKS: 405004: e7 44 add pc, r12
66// FUNC01-THUNKS: 405006: 46 f6 f0 7c movw r12, #28656
67// FUNC01-THUNKS: 40500a: c0 f2 10 0c movt r12, #16
68// FUNC01-THUNKS: 40500e: e7 44 add pc, r12
69// The instruction below is padding from the .balign
70// FUNC01-THUNKS: 405010: cc cc ldm r4!, {r2, r3, r6, r7}
deps/lld/test/COFF/arm-thumb-thunks-pdb.s created+18
...@@ -0,0 +1,18 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE
4
5// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes
6
7 .syntax unified
8 .globl main
9 .globl func1
10 .text
11main:
12 bne func1
13 bx lr
14 .section .text$a, "xr"
15 .space 0x100000
16 .section .text$b, "xr"
17func1:
18 bx lr
deps/lld/test/COFF/arm-thumb-thunks.s created+75
...@@ -0,0 +1,75 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
4// RUN: llvm-objdump -d %t.exe -start-address=0x401000 -stop-address=0x401022 | FileCheck -check-prefix=MAIN %s
5// RUN: llvm-objdump -d %t.exe -start-address=0x501022 -stop-address=0x501032 | FileCheck -check-prefix=FUNC1 %s
6// RUN: llvm-objdump -d %t.exe -start-address=0x601032 | FileCheck -check-prefix=FUNC2 %s
7
8// VERBOSE: Added 3 thunks with margin {{.*}} in 1 passes
9
10 .syntax unified
11 .globl main
12 .globl func1
13 .text
14main:
15 bne func1
16 bne func2
17 // This should reuse the same thunk as func1 above
18 bne func1_alias
19 bx lr
20 .section .text$a, "xr"
21 .space 0x100000
22 .section .text$b, "xr"
23func1:
24func1_alias:
25 // This shouldn't reuse the func2 thunk from above, since it is out
26 // of range.
27 bne func2
28 bx lr
29 .section .text$c, "xr"
30 .space 0x100000
31 .section .text$d, "xr"
32func2:
33// Test using string tail merging. This is irrelevant to the thunking itself,
34// but running multiple passes of assignAddresses() calls finalizeAddresses()
35// multiple times; check that MergeChunk handles this correctly.
36 movw r0, :lower16:"??_C@string1"
37 movt r0, :upper16:"??_C@string1"
38 movw r1, :lower16:"??_C@string2"
39 movt r1, :upper16:"??_C@string2"
40 bx lr
41
42 .section .rdata,"dr",discard,"??_C@string1"
43 .globl "??_C@string1"
44"??_C@string1":
45 .asciz "foobar"
46 .section .rdata,"dr",discard,"??_C@string2"
47 .globl "??_C@string2"
48"??_C@string2":
49 .asciz "bar"
50
51// MAIN: 401000: 40 f0 05 80 bne.w #10 <.text+0xe>
52// MAIN: 401004: 40 f0 08 80 bne.w #16 <.text+0x18>
53// MAIN: 401008: 40 f0 01 80 bne.w #2 <.text+0xe>
54// MAIN: 40100c: 70 47 bx lr
55// func1 thunk
56// MAIN: 40100e: 40 f2 08 0c movw r12, #8
57// MAIN: 401012: c0 f2 10 0c movt r12, #16
58// MAIN: 401016: e7 44 add pc, r12
59// func2 thunk
60// MAIN: 401018: 40 f2 0e 0c movw r12, #14
61// MAIN: 40101c: c0 f2 20 0c movt r12, #32
62// MAIN: 401020: e7 44 add pc, r12
63
64// FUNC1: 501022: 40 f0 01 80 bne.w #2 <.text+0x100028>
65// FUNC1: 501026: 70 47 bx lr
66// func2 thunk
67// FUNC1: 501028: 4f f6 fe 7c movw r12, #65534
68// FUNC1: 50102c: c0 f2 0f 0c movt r12, #15
69// FUNC1: 501030: e7 44 add pc, r12
70
71// FUNC2: 601032: 42 f2 00 00 movw r0, #8192
72// FUNC2: 601036: c0 f2 60 00 movt r0, #96
73// FUNC2: 60103a: 42 f2 03 01 movw r1, #8195
74// FUNC2: 60103e: c0 f2 60 01 movt r1, #96
75// FUNC2: 601042: 70 47 bx lr
deps/lld/test/COFF/arm64-branch-range.test deleted-16
...@@ -1,16 +0,0 @@
1// REQUIRES: aarch64
2
3// RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s
4// RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s
5// RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s
6
7// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj
8// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj
9// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj
10// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj
11
12// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
13// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
14// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
15
16// CHECK: relocation out of range
deps/lld/test/COFF/arm64-delayimport.yaml created+91
...@@ -0,0 +1,91 @@
1# REQUIRES: aarch64
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib /alternatename:__delayLoadHelper2=main /delayload:library.dll
5# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix DISASM
6# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
7
8# DISASM: 140001014: 11 00 00 d0 adrp x17, #8192
9# DISASM: 140001018: 31 22 00 91 add x17, x17, #8
10# DISASM: 14000101c: fd 7b b3 a9 stp x29, x30, [sp, #-208]!
11# DISASM: 140001020: fd 03 00 91 mov x29, sp
12# DISASM: 140001024: e0 07 01 a9 stp x0, x1, [sp, #16]
13# DISASM: 140001028: e2 0f 02 a9 stp x2, x3, [sp, #32]
14# DISASM: 14000102c: e4 17 03 a9 stp x4, x5, [sp, #48]
15# DISASM: 140001030: e6 1f 04 a9 stp x6, x7, [sp, #64]
16# DISASM: 140001034: e0 87 02 ad stp q0, q1, [sp, #80]
17# DISASM: 140001038: e2 8f 03 ad stp q2, q3, [sp, #112]
18# DISASM: 14000103c: e4 97 04 ad stp q4, q5, [sp, #144]
19# DISASM: 140001040: e6 9f 05 ad stp q6, q7, [sp, #176]
20# DISASM: 140001044: e1 03 11 aa mov x1, x17
21# DISASM: 140001048: 00 00 00 b0 adrp x0, #4096
22# DISASM: 14000104c: 00 00 00 91 add x0, x0, #0
23# DISASM: 140001050: ec ff ff 97 bl #-80 <.text>
24# DISASM: 140001054: f0 03 00 aa mov x16, x0
25# DISASM: 140001058: e6 9f 45 ad ldp q6, q7, [sp, #176]
26# DISASM: 14000105c: e4 97 44 ad ldp q4, q5, [sp, #144]
27# DISASM: 140001060: e2 8f 43 ad ldp q2, q3, [sp, #112]
28# DISASM: 140001064: e0 87 42 ad ldp q0, q1, [sp, #80]
29# DISASM: 140001068: e6 1f 44 a9 ldp x6, x7, [sp, #64]
30# DISASM: 14000106c: e4 17 43 a9 ldp x4, x5, [sp, #48]
31# DISASM: 140001070: e2 0f 42 a9 ldp x2, x3, [sp, #32]
32# DISASM: 140001074: e0 07 41 a9 ldp x0, x1, [sp, #16]
33# DISASM: 140001078: fd 7b cd a8 ldp x29, x30, [sp], #208
34# DISASM: 14000107c: 00 02 1f d6 br x16
35
36# IMPORTS: Format: COFF-ARM64
37# IMPORTS: Arch: aarch64
38# IMPORTS: AddressSize: 64bit
39# IMPORTS: DelayImport {
40# IMPORTS: Name: library.dll
41# IMPORTS: Attributes: 0x1
42# IMPORTS: ModuleHandle: 0x3000
43# IMPORTS: ImportAddressTable: 0x3008
44# IMPORTS: ImportNameTable: 0x2040
45# IMPORTS: BoundDelayImportTable: 0x0
46# IMPORTS: UnloadDelayImportTable: 0x0
47# IMPORTS: Import {
48# IMPORTS: Symbol: function (0)
49# IMPORTS: Address: 0x140001014
50# IMPORTS: }
51# IMPORTS: }
52
53--- !COFF
54header:
55 Machine: IMAGE_FILE_MACHINE_ARM64
56 Characteristics: [ ]
57sections:
58 - Name: .text
59 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
60 Alignment: 4
61 SectionData: 00000094C0035FD6
62 Relocations:
63 - VirtualAddress: 0
64 SymbolName: function
65 Type: IMAGE_REL_ARM64_BRANCH26
66symbols:
67 - Name: .text
68 Value: 0
69 SectionNumber: 1
70 SimpleType: IMAGE_SYM_TYPE_NULL
71 ComplexType: IMAGE_SYM_DTYPE_NULL
72 StorageClass: IMAGE_SYM_CLASS_STATIC
73 SectionDefinition:
74 Length: 8
75 NumberOfRelocations: 1
76 NumberOfLinenumbers: 0
77 CheckSum: 0
78 Number: 1
79 - Name: main
80 Value: 0
81 SectionNumber: 1
82 SimpleType: IMAGE_SYM_TYPE_NULL
83 ComplexType: IMAGE_SYM_DTYPE_NULL
84 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
85 - Name: function
86 Value: 0
87 SectionNumber: 0
88 SimpleType: IMAGE_SYM_TYPE_NULL
89 ComplexType: IMAGE_SYM_DTYPE_NULL
90 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
91...
deps/lld/test/COFF/arm64-localimport-align.s created+24
...@@ -0,0 +1,24 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe
4// Don't check the output, just make sure it links fine and doesn't
5// error out due to a misaligned load.
6 .text
7 .globl main
8 .globl myfunc
9main:
10 adrp x8, __imp_myfunc
11 ldr x0, [x8, :lo12:__imp_myfunc]
12 br x0
13 ret
14myfunc:
15 ret
16
17 .section .rdata, "dr"
18 // Start the .rdata section with a 4 byte chunk, to expose the alignment
19 // of the next chunk in the section.
20mydata:
21 .byte 42
22 // The synthesized LocalImportChunk gets stored here in the .rdata
23 // section, but needs to get proper 8 byte alignment since it is a
24 // pointer, just like regular LookupChunks in the IAT.
deps/lld/test/COFF/arm64-relocs-imports.test+9-9
...@@ -34,14 +34,14 @@...@@ -34,14 +34,14 @@
34# BEFORE: 64: e0 03 1f 2a mov w0, wzr34# BEFORE: 64: e0 03 1f 2a mov w0, wzr
35# BEFORE: 68: fe 07 41 f8 ldr x30, [sp], #1635# BEFORE: 68: fe 07 41 f8 ldr x30, [sp], #16
36# BEFORE: 6c: c0 03 5f d6 ret36# BEFORE: 6c: c0 03 5f d6 ret
37# BEFORE: 70: 08 00 00 00 <unknown>37# BEFORE: 70: 08 00 00 00 udf #8
38# BEFORE: 74: 00 00 00 00 <unknown>38# BEFORE: 74: 00 00 00 00 udf #0
39# BEFORE: 78: 01 00 00 00 <unknown>39# BEFORE: 78: 01 00 00 00 udf #1
40# BEFORE: 7c: 01 00 00 00 <unknown>40# BEFORE: 7c: 01 00 00 00 udf #1
41# BEFORE: 80: 00 00 00 91 add x0, x0, #041# BEFORE: 80: 00 00 00 91 add x0, x0, #0
42# BEFORE: 84: 00 00 40 91 add x0, x0, #0, lsl #1242# BEFORE: 84: 00 00 40 91 add x0, x0, #0, lsl #12
43# BEFORE: 88: 00 00 40 f9 ldr x0, [x0]43# BEFORE: 88: 00 00 40 f9 ldr x0, [x0]
44# BEFORE: 8c: 01 00 00 00 <unknown>44# BEFORE: 8c: 01 00 00 00 udf #1
45# BEFORE: 90: 20 1a 09 30 adr x0, #7456545# BEFORE: 90: 20 1a 09 30 adr x0, #74565
46# BEFORE: 94: 01 00 00 54 b.ne #046# BEFORE: 94: 01 00 00 54 b.ne #0
47# BEFORE: 98: 00 00 00 36 tbz w0, #0, #047# BEFORE: 98: 00 00 00 36 tbz w0, #0, #0
...@@ -76,13 +76,13 @@...@@ -76,13 +76,13 @@
76# AFTER: 140001068: fe 07 41 f8 ldr x30, [sp], #1676# AFTER: 140001068: fe 07 41 f8 ldr x30, [sp], #16
77# AFTER: 14000106c: c0 03 5f d6 ret77# AFTER: 14000106c: c0 03 5f d6 ret
78# AFTER: 140001070: 10 20 00 40 <unknown>78# AFTER: 140001070: 10 20 00 40 <unknown>
79# AFTER: 140001074: 01 00 00 00 <unknown>79# AFTER: 140001074: 01 00 00 00 udf #1
80# AFTER: 140001078: 09 20 00 00 <unknown>80# AFTER: 140001078: 09 20 00 00 udf #8201
81# AFTER: 14000107c: 09 00 00 00 <unknown>81# AFTER: 14000107c: 09 00 00 00 udf #9
82# AFTER: 140001080: 00 20 0e 91 add x0, x0, #90482# AFTER: 140001080: 00 20 0e 91 add x0, x0, #904
83# AFTER: 140001084: 00 04 40 91 add x0, x0, #1, lsl #1283# AFTER: 140001084: 00 04 40 91 add x0, x0, #1, lsl #12
84# AFTER: 140001088: 00 c4 41 f9 ldr x0, [x0, #904]84# AFTER: 140001088: 00 c4 41 f9 ldr x0, [x0, #904]
85# AFTER: 14000108c: 03 00 00 00 <unknown>85# AFTER: 14000108c: 03 00 00 00 udf #3
86# AFTER: 140001090: e0 95 09 30 adr x0, #7852586# AFTER: 140001090: e0 95 09 30 adr x0, #78525
87# AFTER: 140001094: 41 00 00 54 b.ne #887# AFTER: 140001094: 41 00 00 54 b.ne #8
88# AFTER: 140001098: 20 00 00 36 tbz w0, #0, #488# AFTER: 140001098: 20 00 00 36 tbz w0, #0, #4
deps/lld/test/COFF/arm64-thunks.s created+27
...@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
4// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
5
6// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes
7
8 .globl main
9 .globl func1
10 .text
11main:
12 tbz w0, #0, func1
13 ret
14 .section .text$a, "xr"
15 .space 0x8000
16 .section .text$b, "xr"
17func1:
18 ret
19
20// DISASM: 0000000140001000 .text:
21// DISASM: 140001000: 40 00 00 36 tbz w0, #0, #8 <.text+0x8>
22// DISASM: 140001004: c0 03 5f d6 ret
23// DISASM: 140001008: 50 00 00 90 adrp x16, #32768
24// DISASM: 14000100c: 10 52 00 91 add x16, x16, #20
25// DISASM: 140001010: 00 02 1f d6 br x16
26
27// DISASM: 140009014: c0 03 5f d6 ret
deps/lld/test/COFF/associative-comdat-mingw.s+3-2
...@@ -11,10 +11,11 @@...@@ -11,10 +11,11 @@
11# CHECK: Number: 211# CHECK: Number: 2
12# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)12# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)
13# This is the critical check to show that only *one* definition of13# This is the critical check to show that only *one* definition of
14# .xdata$foo was retained. This *must* be 4.14# .xdata$foo was retained. This *must* be 0x24 (0x4 for the .xdata
15# section and 0x20 for the .ctors/.dtors headers/ends).
15# Make sure that no other .xdata sections get included, which would16# Make sure that no other .xdata sections get included, which would
16# increase the size here.17# increase the size here.
17# CHECK-NEXT: VirtualSize: 0x418# CHECK-NEXT: VirtualSize: 0x24
1819
19 .text20 .text
20 .def main;21 .def main;
deps/lld/test/COFF/autoimport-arm-code.s created+19
...@@ -0,0 +1,19 @@
1# REQUIRES: arm
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s
9
10# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM_MOV32T
11
12 .global main
13 .text
14 .thumb
15main:
16 movw r0, :lower16:variable
17 movt r0, :upper16:variable
18 ldr r0, [r0]
19 bx lr
deps/lld/test/COFF/autoimport-arm-data.s created+42
...@@ -0,0 +1,42 @@
1# REQUIRES: arm
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
9
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
11# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
12
13# IMPORTS: Import {
14# IMPORTS-NEXT: Name: autoimport-arm-data.s.tmp-lib.dll
15# IMPORTS-NEXT: ImportLookupTableRVA: 0x2050
16# IMPORTS-NEXT: ImportAddressTableRVA: 0x2058
17# IMPORTS-NEXT: Symbol: variable (0)
18# IMPORTS-NEXT: }
19
20# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
21# First runtime pseudo reloc, with import from 0x2058,
22# applied at 0x3000, with a size of 32 bits.
23# CONTENTS: Contents of section .rdata:
24# CONTENTS: 402000 00000000 00000000 01000000 58200000
25# CONTENTS: 402010 00300000 20000000
26# ptr: pointing at the IAT RVA at 0x2058
27# relocs: pointing at the runtime pseudo reloc list at
28# 0x2000 - 0x2018.
29# CONTENTS: Contents of section .data:
30# CONTENTS: 403000 58204000 00204000 18204000
31
32 .global main
33 .text
34 .thumb
35main:
36 bx lr
37 .data
38ptr:
39 .long variable
40relocs:
41 .long __RUNTIME_PSEUDO_RELOC_LIST__
42 .long __RUNTIME_PSEUDO_RELOC_LIST_END__
deps/lld/test/COFF/autoimport-arm64-code.s created+18
...@@ -0,0 +1,18 @@
1# REQUIRES: aarch64
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s
9
10# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM64_PAGEBASE_REL21
11# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM64_PAGEOFFSET_12L
12
13 .global main
14 .text
15main:
16 adrp x0, variable
17 ldr w0, [x0, :lo12:variable]
18 ret
deps/lld/test/COFF/autoimport-arm64-data.s created+42
...@@ -0,0 +1,42 @@
1# REQUIRES: aarch64
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
9
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
11# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
12
13# IMPORTS: Import {
14# IMPORTS-NEXT: Name: autoimport-arm64-data.s.tmp-lib.dll
15# IMPORTS-NEXT: ImportLookupTableRVA: 0x2060
16# IMPORTS-NEXT: ImportAddressTableRVA: 0x2070
17# IMPORTS-NEXT: Symbol: variable (0)
18# IMPORTS-NEXT: }
19
20# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
21# First runtime pseudo reloc, with import from 0x2070,
22# applied at 0x3000, with a size of 32 bits.
23# CONTENTS: Contents of section .rdata:
24# CONTENTS: 140002000 00000000 00000000 01000000 70200000
25# CONTENTS: 140002010 00300000 40000000
26# ptr: pointing at the IAT RVA at 0x2070
27# relocs: pointing at the runtime pseudo reloc list at
28# 0x2000 - 0x2018.
29# CONTENTS: Contents of section .data:
30# CONTENTS: 140003000 70200040 01000000 00200040 01000000
31# CONTENTS: 140003010 18200040 01000000
32
33 .global main
34 .text
35main:
36 ret
37 .data
38ptr:
39 .quad variable
40relocs:
41 .quad __RUNTIME_PSEUDO_RELOC_LIST__
42 .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
deps/lld/test/COFF/autoimport-gnu-implib.s created+26
...@@ -0,0 +1,26 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
4# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-data.s -filetype=obj -o %t-dabcds00000.o
5# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
6# RUN: rm -f %t-implib.a
7# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
8
9# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
10# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-implib.a -verbose
11
12# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
13
14# IMPORTS: Import {
15# IMPORTS-NEXT: Name: foo.dll
16# IMPORTS-NEXT: ImportLookupTableRVA:
17# IMPORTS-NEXT: ImportAddressTableRVA:
18# IMPORTS-NEXT: Symbol: data (0)
19# IMPORTS-NEXT: }
20
21 .global main
22 .text
23main:
24 movl data(%rip), %eax
25 ret
26 .data
deps/lld/test/COFF/autoimport-list-ptrs.s created+20
...@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
4# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj -verbose
5
6# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
7
8# Even if we didn't actually write any pseudo relocations,
9# check that the synthetic pointers still are set to a non-null value
10# CONTENTS: Contents of section .data:
11# CONTENTS: 140003000 00200040 01000000 00200040 01000000
12
13 .global main
14 .text
15main:
16 retq
17 .data
18relocs:
19 .quad __RUNTIME_PSEUDO_RELOC_LIST__
20 .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
deps/lld/test/COFF/autoimport-refptr.s created+65
...@@ -0,0 +1,65 @@
1# REQUIRES: x86
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
9
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
11# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
12# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
13
14# IMPORTS: Import {
15# IMPORTS-NEXT: Name: autoimport-refptr.s.tmp-lib.dll
16# IMPORTS-NEXT: ImportLookupTableRVA: 0x2050
17# IMPORTS-NEXT: ImportAddressTableRVA: 0x2060
18# IMPORTS-NEXT: Symbol: variable (0)
19# IMPORTS-NEXT: }
20
21# DISASM: Disassembly of section .text:
22# DISASM: .text:
23# Relative offset at 0x1002 pointing at the IAT at 0x2060
24# DISASM: 140001000: 48 8b 05 59 10 00 00 movq 4185(%rip), %rax
25# DISASM: 140001007: 8b 00 movl (%rax), %eax
26# Relative offset at 0x100b pointing at the .refptr.localvar stub at
27# 0x2000
28# DISASM: 140001009: 48 8b 0d f0 0f 00 00 movq 4080(%rip), %rcx
29# DISASM: 140001010: 03 01 addl (%rcx), %eax
30# DISASM: 140001012: c3 retq
31
32# relocs: pointing at an empty list of runtime pseudo relocs.
33# localvar: 42
34# CONTENTS: Contents of section .data:
35# CONTENTS: 140003000 08200040 01000000 08200040 01000000
36# CONTENTS: 140003010 2a000000
37
38 .global main
39 .global localvar
40 .text
41main:
42 movq .refptr.variable(%rip), %rax
43 movl (%rax), %eax
44 movq .refptr.localvar(%rip), %rcx
45 addl (%rcx), %eax
46 ret
47
48 .data
49relocs:
50 .quad __RUNTIME_PSEUDO_RELOC_LIST__
51 .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
52localvar:
53 .int 42
54
55# Normally the compiler wouldn't emit a stub for a variable that is
56# emitted in the same translation unit.
57 .section .rdata$.refptr.localvar,"dr",discard,.refptr.localvar
58 .global .refptr.localvar
59.refptr.localvar:
60 .quad localvar
61
62 .section .rdata$.refptr.variable,"dr",discard,.refptr.variable
63 .global .refptr.variable
64.refptr.variable:
65 .quad variable
deps/lld/test/COFF/autoimport-x86.s created+53
...@@ -0,0 +1,53 @@
1# REQUIRES: x86
2
3# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
4# RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
5# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
6
7# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
8# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
9
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
11# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
12# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
13
14# IMPORTS: Import {
15# IMPORTS-NEXT: Name: autoimport-x86.s.tmp-lib.dll
16# IMPORTS-NEXT: ImportLookupTableRVA: 0x2070
17# IMPORTS-NEXT: ImportAddressTableRVA: 0x2080
18# IMPORTS-NEXT: Symbol: variable (0)
19# IMPORTS-NEXT: }
20
21# DISASM: Disassembly of section .text:
22# DISASM: .text:
23# Relative offset at 0x1002 pointing at the IAT at 0x2080.
24# DISASM: 140001000: 8b 05 7a 10 00 00 movl 4218(%rip), %eax
25# DISASM: 140001006: c3 retq
26
27# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
28# First runtime pseudo reloc, with import from 0x2080,
29# applied at 0x1002, with a size of 32 bits.
30# Second runtime pseudo reloc, with import from 0x2080,
31# applied at 0x3000, with a size of 64 bits.
32# CONTENTS: Contents of section .rdata:
33# CONTENTS: 140002000 00000000 00000000 01000000 80200000
34# CONTENTS: 140002010 02100000 20000000 80200000 00300000
35# CONTENTS: 140002020 40000000
36# ptr: pointing at the IAT RVA at 0x2080
37# relocs: pointing at the runtime pseudo reloc list at
38# 0x2000 - 0x2024.
39# CONTENTS: Contents of section .data:
40# CONTENTS: 140003000 80200040 01000000 00200040 01000000
41# CONTENTS: 140003010 24200040 01000000
42
43 .global main
44 .text
45main:
46 movl variable(%rip), %eax
47 ret
48 .data
49ptr:
50 .quad variable
51relocs:
52 .quad __RUNTIME_PSEUDO_RELOC_LIST__
53 .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
deps/lld/test/COFF/baserel.test+3-3
...@@ -47,9 +47,9 @@...@@ -47,9 +47,9 @@
47# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \47# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \
48# RUN: --check-prefix=BASEREL-HEADER48# RUN: --check-prefix=BASEREL-HEADER
49#49#
50# RN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib50# RUN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
51# RN: llvm-readobj -file-headers %t.exe | FileCheck %s \51# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s \
52# RN: --check-prefix=NOBASEREL-HEADER52# RUN: --check-prefix=NOBASEREL-HEADER
53#53#
54# BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED54# BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
55#55#
deps/lld/test/COFF/broken-arm-reloc.yaml created+92
...@@ -0,0 +1,92 @@
1# REQUIRES: arm
2
3# .global main
4# .global variable
5# .text
6# .thumb
7#main:
8# movw r0, :lower16:variable
9# nop
10# movt r0, :upper16:variable
11# ldr r0, [r0]
12# bx lr
13# .data
14#variable:
15# .long 42
16
17# RUN: yaml2obj %s > %t.obj
18# RUN: not lld-link -out:%t.exe -entry:main %t.obj 2>&1 | FileCheck %s
19
20# CHECK: error: unexpected instruction in MOVT instruction in MOV32T relocation
21
22--- !COFF
23header:
24 Machine: IMAGE_FILE_MACHINE_ARMNT
25 Characteristics: [ ]
26sections:
27 - Name: .text
28 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
29 Alignment: 4
30 SectionData: 40F2000000BFC0F2000000687047
31 Relocations:
32 - VirtualAddress: 0
33 SymbolName: variable
34 Type: IMAGE_REL_ARM_MOV32T
35 - Name: .data
36 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
37 Alignment: 4
38 SectionData: 2A000000
39 - Name: .bss
40 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
41 Alignment: 4
42 SectionData: ''
43symbols:
44 - Name: .text
45 Value: 0
46 SectionNumber: 1
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_STATIC
50 SectionDefinition:
51 Length: 14
52 NumberOfRelocations: 1
53 NumberOfLinenumbers: 0
54 CheckSum: 2762100735
55 Number: 1
56 - Name: .data
57 Value: 0
58 SectionNumber: 2
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_NULL
61 StorageClass: IMAGE_SYM_CLASS_STATIC
62 SectionDefinition:
63 Length: 4
64 NumberOfRelocations: 0
65 NumberOfLinenumbers: 0
66 CheckSum: 3482275674
67 Number: 2
68 - Name: .bss
69 Value: 0
70 SectionNumber: 3
71 SimpleType: IMAGE_SYM_TYPE_NULL
72 ComplexType: IMAGE_SYM_DTYPE_NULL
73 StorageClass: IMAGE_SYM_CLASS_STATIC
74 SectionDefinition:
75 Length: 0
76 NumberOfRelocations: 0
77 NumberOfLinenumbers: 0
78 CheckSum: 0
79 Number: 3
80 - Name: main
81 Value: 0
82 SectionNumber: 1
83 SimpleType: IMAGE_SYM_TYPE_NULL
84 ComplexType: IMAGE_SYM_DTYPE_NULL
85 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
86 - Name: variable
87 Value: 0
88 SectionNumber: 2
89 SimpleType: IMAGE_SYM_TYPE_NULL
90 ComplexType: IMAGE_SYM_DTYPE_NULL
91 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
92...
deps/lld/test/COFF/comdat-jumptable.s created+70
...@@ -0,0 +1,70 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj
3# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/comdat-jumptable2.s -filetype=obj -o %t2.obj
4
5# RUN: llvm-objdump -s %t1.obj | FileCheck --check-prefix=OBJ1 %s
6# RUN: llvm-objdump -s %t2.obj | FileCheck --check-prefix=OBJ2 %s
7
8# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe
9# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=EXE %s
10
11# Test linking cases where comdat functions have an associated jump table
12# in a non-comdat rdata (which GCC produces for functions with jump tables).
13# In these cases, ld.bfd keeps all rdata sections, but the relocations that
14# refer to discarded comdat sections just are emitted as they were originally.
15
16# In real scenarios, the jump table .rdata section should be identical across
17# all object files; here it is different to illustrate more clearly what
18# the linker actually does.
19
20# OBJ1: Contents of section .rdata:
21# OBJ1: 0000 aaaaaaaa 14000000 1e000000 28000000
22# OBJ1: 0010 bbbbbbbb
23
24# OBJ2: Contents of section .rdata:
25# OBJ2: 0000 cccccccc 14000000 1e000000 28000000
26# OBJ2: 0010 dddddddd
27
28# EXE: Contents of section .rdata:
29# EXE: 140002000 aaaaaaaa 0c100000 12100000 18100000
30# EXE: 140002010 bbbbbbbb cccccccc 14000000 1e000000
31# EXE: 140002020 28000000 dddddddd
32
33
34 .section .text@comdatfunc, "x"
35 .linkonce discard
36 .globl comdatfunc
37comdatfunc:
38 leaq .Ljumptable(%rip), %rax
39 movslq (%rax, %rcx, 4), %rcx
40 addq %rcx, %rax
41 jmp *%rax
42
43 .section .rdata, "dr"
44 .long 0xaaaaaaaa
45.Ljumptable:
46 .long .Ltail1-.Ljumptable
47 .long .Ltail2-.Ljumptable
48 .long .Ltail3-.Ljumptable
49 .long 0xbbbbbbbb
50
51 .section .text@comdatfunc, "x"
52# If assembled with binutils, the following line can be kept in:
53# .linkonce discard
54.Ltail1:
55 movl $1, %eax
56 ret
57.Ltail2:
58 movl $2, %eax
59 ret
60.Ltail3:
61 movl $3, %eax
62 ret
63
64
65 .text
66 .globl main
67main:
68 call comdatfunc
69 call otherfunc
70 ret
deps/lld/test/COFF/comdat-weak.test created+82
...@@ -0,0 +1,82 @@
1RUN: lld-link -lldmingw %S/Inputs/inline-weak.o %S/Inputs/inline-weak2.o -out:%t.exe
2
3When compiling certain forms of templated inline functions, some
4versions of GCC (tested with 5.4) produces a weak symbol for the function.
5Newer versions of GCC don't do this though.
6
7The bundled object files are an example of that, they can be produced
8with test code like this:
9
10$ cat inline-weak.h
11class MyClass {
12public:
13 template<typename... _Args> int get(_Args&&... args) {
14 return a;
15 }
16private:
17 int a;
18};
19
20$ cat inline-weak.cpp
21#include "inline-weak.h"
22
23int get(MyClass& a);
24
25int main(int argc, char* argv[]) {
26 MyClass a;
27 int ret = a.get();
28 ret += get(a);
29 return ret;
30}
31extern "C" void mainCRTStartup(void) {
32 main(0, (char**)0);
33}
34extern "C" void __main(void) {
35}
36
37$ cat inline-weak2.cpp
38#include "inline-weak.h"
39
40int get(MyClass& a) {
41 return a.get();
42}
43
44$ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak.cpp
45$ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak2.cpp
46
47$ x86_64-w64-mingw32-nm inline-weak.o | grep MyClass3get
480000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
490000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
500000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_.main
510000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
52 w _ZN7MyClass3getIIEEEiDpOT_
530000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
54
55$ x86_64-w64-mingw32-nm inline-weak2.o | grep MyClass3get
560000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
570000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
580000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_._Z3getR7MyClass
590000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
60 w _ZN7MyClass3getIIEEEiDpOT_
610000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
62
63This can't be reproduced by assembling .s files with llvm-mc, since that
64always produces a symbol named .weak.<weaksymbol>.default, therefore
65the test uses prebuilt object files instead.
66
67In these cases, the undefined weak symbol points to the regular symbol
68.weak._ZN7MyClass3getIIEEEiDpOT_.<othersymbol>, where <othersymbol>
69varies among the object files that emit the same function. This regular
70symbol points to the same location as the comdat function
71_ZN7MyClass3getIJEEEiDpOT_.
72
73When linking, the comdat section from the second object file gets
74discarded, as it matches the one that already exists. This means that
75the uniquely named symbol .weak.<weakname>.<othername> points to a
76discarded section chunk.
77
78Previously, this would have triggered adding an Undefined symbol for
79this case, which would later break linking. However, also previously,
80if the second object file is linked in via a static library, this
81leftover symbol is retained as a Lazy symbol, which would make the link
82succeed.
deps/lld/test/COFF/common-replacement.s+1-1
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
1414
15# SECTIONS: Name: .data (2E 64 61 74 61 00 00 00)15# SECTIONS: Name: .data (2E 64 61 74 61 00 00 00)
16# SECTIONS-NEXT: VirtualSize: 0x816# SECTIONS-NEXT: VirtualSize: 0x8
17# SECTIONS-NEXT: VirtualAddress: 0x200017# SECTIONS-NEXT: VirtualAddress: 0x3000
18# SECTIONS-NEXT: RawDataSize: 51218# SECTIONS-NEXT: RawDataSize: 512
1919
2020
deps/lld/test/COFF/could-not-open.test created+5
...@@ -0,0 +1,5 @@
1RUN: not lld-link 01 2>&1 | FileCheck %s
2
3CHECK: could not open 01
4CHECK-NOT: /machine is not specified
5CHECK-NOT: subsystem must be defined
deps/lld/test/COFF/crt-dyn-initializer-order.test created+100
...@@ -0,0 +1,100 @@
1# // a.cpp
2# #include <iostream>
3# #include <vector>
4#
5# template <int Magic> struct TemplatedObject {
6# static std::vector<TemplatedObject<Magic> *> Instances;
7# TemplatedObject() { Instances.push_back(this); }
8# };
9#
10# using Object = TemplatedObject<0>;
11# template <> std::vector<Object *> Object::Instances{};
12# Object idle{};
13#
14# int main() {
15# if (Object::Instances.size() == 0)
16# std::cout << "It's broken" << std::endl;
17# else
18# std::cout << "It works!" << std::endl;
19# return 0;
20# }
21# // using `clang-cl /c a.cpp | lld-link a.obj` works
22# // using `cl /c a.cpp | lld-link a.obj` fails without lld/COFF/Writer.cpp/Writer::sortSectionChunks()
23
24# RUN: yaml2obj %s > %t.obj
25# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_1.yaml > %t1.obj
26# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_2.yaml > %t2.obj
27
28# CHECK: Name: .CRT
29# CHECK: Characteristics [
30# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
31# CHECK-NEXT: IMAGE_SCN_MEM_READ
32# CHECK-NEXT: ]
33# CHECK-NEXT: SectionData (
34
35# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t1.obj %t2.obj
36# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE1
37# CASE1-NEXT: 01020304 55701011 1205
38
39# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t2.obj %t1.obj
40# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE2
41# CASE2-NEXT: 01020304 10111255 7005
42
43# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t2.obj %t.obj
44# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE3
45# CASE3-NEXT: 01557010 11120203 0405
46
47# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t.obj %t2.obj
48# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE4
49# CASE4-NEXT: 01557002 03041011 1205
50
51# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t1.obj %t.obj
52# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE5
53# CASE5-NEXT: 01101112 55700203 0405
54
55# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t.obj %t1.obj
56# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE6
57# CASE6-NEXT: 01101112 02030455 7005
58
59# CHECK-NEXT: )
60
61--- !COFF
62header:
63 Machine: IMAGE_FILE_MACHINE_AMD64
64 Characteristics: [ ]
65sections:
66 - Name: '.CRT$XCA'
67 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
68 Alignment: 1
69 SectionData: 01
70 - Name: '.CRT$XCU'
71 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
72 Alignment: 1
73 SectionData: 02
74 - Name: '.CRT$XCU'
75 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]
76 Alignment: 1
77 SectionData: 03
78 - Name: '.CRT$XCU'
79 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
80 Alignment: 1
81 SectionData: 04
82 - Name: '.CRT$XCZ'
83 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
84 Alignment: 1
85 SectionData: 05
86symbols:
87 - Name: '.CRT$XCU'
88 Value: 0
89 SectionNumber: 3
90 SimpleType: IMAGE_SYM_TYPE_NULL
91 ComplexType: IMAGE_SYM_DTYPE_NULL
92 StorageClass: IMAGE_SYM_CLASS_STATIC
93 SectionDefinition:
94 Length: 1
95 NumberOfRelocations: 0
96 NumberOfLinenumbers: 0
97 CheckSum: 1
98 Number: 2
99 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
100...
deps/lld/test/COFF/ctors_dtors_priority.s+25-10
...@@ -1,12 +1,17 @@...@@ -1,12 +1,17 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s2# RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s
3# RUN: lld-link -entry:main %t.obj -out:%t.exe3# RUN: lld-link -lldmingw -entry:main %t.obj -out:%t.exe
4# RUN: llvm-objdump -s %t.exe | FileCheck %s4# RUN: llvm-objdump -s %t.exe | FileCheck %s
55
6.globl main6.globl main
7main:7main:
8 nop8 nop
99
10# Check that these symbols point at the right spots.
11.data
12 .quad __CTOR_LIST__
13 .quad __DTOR_LIST__
14
10.section .ctors.00005, "w"15.section .ctors.00005, "w"
11 .quad 216 .quad 2
12.section .ctors, "w"17.section .ctors, "w"
...@@ -15,16 +20,26 @@ main:...@@ -15,16 +20,26 @@ main:
15 .quad 320 .quad 3
1621
17.section .dtors, "w"22.section .dtors, "w"
18 .quad 123 .quad 4
19.section .dtors.00100, "w"24.section .dtors.00100, "w"
20 .quad 325 .quad 6
21.section .dtors.00005, "w"26.section .dtors.00005, "w"
22 .quad 227 .quad 5
28
29# Also test that the .CRT section is merged into .rdata
2330
24# CHECK: Contents of section .ctors:31.section .CRT$XCA, "dw"
25# CHECK-NEXT: 140002000 01000000 00000000 02000000 0000000032 .quad 7
26# CHECK-NEXT: 140002010 03000000 0000000033 .quad 8
2734
28# CHECK: Contents of section .dtors:35# CHECK: Contents of section .rdata:
29# CHECK-NEXT: 140003000 01000000 00000000 02000000 0000000036# CHECK-NEXT: 140002000 07000000 00000000 08000000 00000000
30# CHECK-NEXT: 140003010 03000000 0000000037# CHECK-NEXT: 140002010 ffffffff ffffffff 01000000 00000000
38# CHECK-NEXT: 140002020 02000000 00000000 03000000 00000000
39# CHECK-NEXT: 140002030 00000000 00000000 ffffffff ffffffff
40# CHECK-NEXT: 140002040 04000000 00000000 05000000 00000000
41# CHECK-NEXT: 140002050 06000000 00000000 00000000 00000000
42# __CTOR_LIST__ pointing at 0x140002010 and
43# __DTOR_LIST__ pointing at 0x140002038.
44# CHECK-NEXT: Contents of section .data:
45# CHECK-NEXT: 140003000 10200040 01000000 38200040 01000000
deps/lld/test/COFF/debug-fastlink.test created+12
...@@ -0,0 +1,12 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3
4; If /DEBUG:FASTLINK is specified, /DEBUG:FULL is used instead
5# RUN: rm -f %t.pdb
6# RUN: lld-link /DEBUG /pdb:%t.pdb /DEBUG:FASTLINK /entry:main /nodefaultlib %t1.obj %t2.obj \
7# RUN: 2>&1 | FileCheck %s
8
9# CHECK: /debug:fastlink unsupported; using /debug:full
10
11# RUN: ls %t.pdb
12
deps/lld/test/COFF/debug-reloc.s+9-9
...@@ -8,35 +8,35 @@...@@ -8,35 +8,35 @@
8# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s -check-prefix HEADERS8# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s -check-prefix HEADERS
9# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG9# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG
1010
11# SECTIONS: Number: 211# SECTIONS: Number: 3
12# SECTIONS-NEXT: Name: .buildid (2E 62 75 69 6C 64 69 64)12# SECTIONS-NEXT: Name: .buildid (2E 62 75 69 6C 64 69 64)
13# SECTIONS-NEXT: VirtualSize: 0x3513# SECTIONS-NEXT: VirtualSize: 0x35
14# SECTIONS-NEXT: VirtualAddress: 0x200014# SECTIONS-NEXT: VirtualAddress: 0x3000
15# SECTIONS: Number: 315# SECTIONS: Number: 4
16# SECTIONS-NEXT: Name: .data (2E 64 61 74 61 00 00 00)16# SECTIONS-NEXT: Name: .data (2E 64 61 74 61 00 00 00)
17# SECTIONS-NEXT: VirtualSize: 0x817# SECTIONS-NEXT: VirtualSize: 0x8
18# SECTIONS-NEXT: VirtualAddress: 0x300018# SECTIONS-NEXT: VirtualAddress: 0x4000
1919
20# RELOCS: BaseReloc [20# RELOCS: BaseReloc [
21# RELOCS-NEXT: Entry {21# RELOCS-NEXT: Entry {
22# RELOCS-NEXT: Type: DIR6422# RELOCS-NEXT: Type: DIR64
23# RELOCS-NEXT: Address: 0x300023# RELOCS-NEXT: Address: 0x4000
24# RELOCS-NEXT: }24# RELOCS-NEXT: }
25# RELOCS-NEXT: Entry {25# RELOCS-NEXT: Entry {
26# RELOCS-NEXT: Type: ABSOLUTE26# RELOCS-NEXT: Type: ABSOLUTE
27# RELOCS-NEXT: Address: 0x300027# RELOCS-NEXT: Address: 0x4000
28# RELOCS-NEXT: }28# RELOCS-NEXT: }
29# RELOCS-NEXT: ]29# RELOCS-NEXT: ]
3030
31# HEADERS: DebugRVA: 0x200031# HEADERS: DebugRVA: 0x3000
32# HEADERS: DebugSize: 0x1C32# HEADERS: DebugSize: 0x1C
3333
34# DEBUG: DebugDirectory [34# DEBUG: DebugDirectory [
35# DEBUG: DebugEntry {35# DEBUG: DebugEntry {
36# DEBUG: Type: CodeView (0x2)36# DEBUG: Type: CodeView (0x2)
37# DEBUG: SizeOfData: 0x1937# DEBUG: SizeOfData: 0x19
38# DEBUG: AddressOfRawData: 0x201C38# DEBUG: AddressOfRawData: 0x301C
39# DEBUG: PointerToRawData: 0x61C39# DEBUG: PointerToRawData: 0x81C
4040
41 .text41 .text
42 .def mainfunc;42 .def mainfunc;
deps/lld/test/COFF/directives.s created+46
...@@ -0,0 +1,46 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=x86_64-windows %s -filetype=obj -o %t.obj
4
5# RUN: lld-link -dll -out:%t.dll -entry:entry %t.obj -subsystem:console
6# RUN: llvm-objdump -p %t.dll | FileCheck %s
7
8# CHECK: Export Table:
9# CHECK: DLL name: directives.s.tmp.dll
10# CHECK: Ordinal RVA Name
11# CHECK-NEXT: 0 0
12# CHECK-NEXT: 1 0x1000 exportfn1
13# CHECK-NEXT: 2 0x1000 exportfn2
14# CHECK-NEXT: 3 0x1000 exportfn3
15# CHECK-NEXT: 4 0x1000 exportfn4
16# CHECK-NEXT: 5 0x1000 exportfn5
17# CHECK-NEXT: 6 0x1000 exportfn6
18
19 .global entry
20 .global exportfn1
21 .global exportfn2
22 .global exportfn3
23 .global exportfn4
24 .global exportfn5
25 .global exportfn6
26 .text
27entry:
28exportfn1:
29exportfn2:
30exportfn3:
31exportfn4:
32exportfn5:
33exportfn6:
34 ret
35 .section .drectve
36# Test that directive strings can be separated by any combination of
37# spaces and null bytes.
38 .ascii "-export:exportfn1 "
39 .asciz "-export:exportfn2"
40 .asciz "-export:exportfn3"
41 .asciz "-export:exportfn4 "
42 .byte 0
43 .ascii " "
44 .byte 0
45 .asciz "-export:exportfn5"
46 .asciz " -export:exportfn6"
deps/lld/test/COFF/duplicate-imp-func.s created+43
...@@ -0,0 +1,43 @@
1# REQUIRES: x86
2
3# RUN: echo -e ".globl libfunc\n.text\nlibfunc:\nret" > %t.lib.s
4# RUN: llvm-mc -triple=x86_64-windows-gnu %t.lib.s -filetype=obj -o %t.lib.o
5# RUN: lld-link -lldmingw -dll -out:%t.lib.dll -entry:libfunc %t.lib.o -implib:%t.lib.dll.a
6
7# RUN: echo -e ".globl helper1\n.text\nhelper1:\ncall libfunc\nret" > %t.helper1.s
8# RUN: echo -e ".globl helper2\n.text\nhelper2:\nret\n.globl libfunc\n.globl __imp_libfunc\nlibfunc:\nret\n.data\n__imp_libfunc:\n.quad libfunc" > %t.helper2.s
9# RUN: llvm-mc -triple=x86_64-windows-gnu %t.helper1.s -filetype=obj -o %t.helper1.o
10# RUN: llvm-mc -triple=x86_64-windows-gnu %t.helper2.s -filetype=obj -o %t.helper2.o
11
12# RUN: llvm-ar rcs %t.helper.a %t.helper1.o %t.helper2.o
13
14# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.main.o
15
16# Simulate a setup, where two libraries provide the same import function;
17# %t.lib.dll.a is a pure import library which provides "libfunc".
18# %t.helper.a is a static library which contains "helper1" and "helper2".
19#
20# helper1 contains an undefined reference to libfunc. helper2 contains a
21# fake local implementation of libfunc, together with the __imp_libfunc
22# stub.
23#
24# %t.lib.dll.a is listed before %t.helper.a on the command line. After
25# including helper1, the library member that first declared the Lazy libfunc
26# (%t.lib.dll.a) gets enqueued to be loaded. Before that gets done, helper2
27# gets loaded, which also turns out to provide a definition of libfunc.
28# Once the import library member from %t.lib.dll.a gets loaded, libfunc
29# and __imp_libfunc already are defined.
30
31# Just check that this fails cleanly (doesn't crash).
32# RUN: not lld-link -lldmingw -out:%t.main.exe -entry:main %t.main.o %t.lib.dll.a %t.helper.a
33
34# Test with %t.helper.a on the command line; in this case we won't try to
35# include libfunc from %t.lib.dll.a and everything works fine.
36# RUN: lld-link -lldmingw -out:%t.main.exe -entry:main %t.main.o %t.helper.a %t.lib.dll.a
37
38 .globl main
39 .text
40main:
41 call helper1
42 call helper2
43 ret
deps/lld/test/COFF/entry-inference-mingw.s created+44
...@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.o
3
4# RUN: lld-link -lldmingw %t.o -out:%t-default.exe 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
5# RUN: lld-link -lldmingw %t.o -out:%t-cui.exe -subsystem:console 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
6# RUN: lld-link -lldmingw %t.o -out:%t-gui.exe -subsystem:windows 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
7
8# RUN: llvm-readobj -file-headers %t-default.exe | FileCheck -check-prefix=CUI %s
9# RUN: llvm-readobj -file-headers %t-cui.exe | FileCheck -check-prefix=CUI %s
10# RUN: llvm-readobj -file-headers %t-gui.exe | FileCheck -check-prefix=GUI %s
11
12# Check that this doesn't print any warnings.
13# LINK-NOT: found both wmain and main
14
15# CUI: AddressOfEntryPoint: 0x1001
16# CUI: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
17
18# GUI: AddressOfEntryPoint: 0x1002
19# GUI: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2)
20
21
22 .text
23 .globl mainCRTStartup
24 .globl WinMainCRTStartup
25# MinGW only uses the entry points above, these other ones aren't
26# used as entry.
27 .globl main
28 .globl wmain
29 .globl wmainCRTStartup
30 .globl wWinMainCRTStartup
31foo:
32 ret
33mainCRTStartup:
34 ret
35WinMainCRTStartup:
36 ret
37main:
38 ret
39wmain:
40 ret
41wmainCRTStartup:
42 ret
43wWinMainCRTStartup:
44 ret
deps/lld/test/COFF/entry-inference.test+8
...@@ -1,18 +1,26 @@...@@ -1,18 +1,26 @@
1# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj1# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
2# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&12# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
3# RUN: FileCheck -check-prefix=MAIN %s < %t.log3# RUN: FileCheck -check-prefix=MAIN %s < %t.log
4# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
5# RUN: FileCheck -check-prefix=MAIN %s < %t.log
46
5# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj7# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
6# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&18# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
7# RUN: FileCheck -check-prefix=WMAIN %s < %t.log9# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
10# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
11# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
812
9# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj13# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
10# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&114# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
11# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log15# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
16# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
17# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
1218
13# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj19# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
14# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&120# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
15# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log21# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
22# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
23# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
1624
17# MAIN: error: <root>: undefined symbol: mainCRTStartup25# MAIN: error: <root>: undefined symbol: mainCRTStartup
18# WMAIN: error: <root>: undefined symbol: wmainCRTStartup26# WMAIN: error: <root>: undefined symbol: wmainCRTStartup
deps/lld/test/COFF/entry-inference4.test+16-4
...@@ -14,10 +14,22 @@...@@ -14,10 +14,22 @@
14# RUN: not lld-link /subsystem:console /out:%t.exe %t.obj > %t.log 2>&114# RUN: not lld-link /subsystem:console /out:%t.exe %t.obj > %t.log 2>&1
15# RUN: FileCheck -check-prefix=WMAIN %s < %t.log15# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
1616
17# MAIN: error: <root>: undefined symbol: mainCRTStartup17# RUN: sed 's/ENTRY1/wmain/;s/ENTRY2/main/' %s | yaml2obj > %t.obj
18# WMAIN: error: <root>: undefined symbol: wmainCRTStartup18# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
19# WINMAIN: error: <root>: undefined symbol: WinMainCRTStartup19# RUN: FileCheck -check-prefix=MAINWMAIN %s < %t.log
20# WWINMAIN: error: <root>: undefined symbol: wWinMainCRTStartup20
21# RUN: sed 's/ENTRY1/wWinMain/;s/ENTRY2/WinMain/' %s | yaml2obj > %t.obj
22# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
23# RUN: FileCheck -check-prefix=WINMAINWWINMAIN %s < %t.log
24
25# MAIN: error: <root>: undefined symbol: mainCRTStartup
26# WMAIN: error: <root>: undefined symbol: wmainCRTStartup
27# MAINWMAIN: warning: found both wmain and main; using latter
28# MAINWMAIN: error: <root>: undefined symbol: mainCRTStartup
29# WINMAIN: error: <root>: undefined symbol: WinMainCRTStartup
30# WWINMAIN: error: <root>: undefined symbol: wWinMainCRTStartup
31# WINMAINWWINMAIN: warning: found both wWinMain and WinMain; using latter
32# WINMAINWWINMAIN: error: <root>: undefined symbol: WinMainCRTStartup
2133
22--- !COFF34--- !COFF
23header:35header:
deps/lld/test/COFF/export-all.s+21-6
...@@ -3,14 +3,13 @@...@@ -3,14 +3,13 @@
3# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj3# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
44
5# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj -implib:%t.lib5# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj -implib:%t.lib
6# RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s6# RUN: llvm-readobj -coff-exports %t.dll | grep Name: | FileCheck %s
7# RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s7# RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s
88
9# CHECK-NOT: Name: DllMainCRTStartup9# CHECK: Name:
10# CHECK-NOT: Name: _imp__unexported10# CHECK-NEXT: Name: dataSym
11# CHECK: Name: dataSym11# CHECK-NEXT: Name: foobar
12# CHECK: Name: foobar12# CHECK-EMPTY:
13# CHECK-NOT: Name: unexported
1413
15# IMPLIB: Symbol: __imp__dataSym14# IMPLIB: Symbol: __imp__dataSym
16# IMPLIB-NOT: Symbol: _dataSym15# IMPLIB-NOT: Symbol: _dataSym
...@@ -22,6 +21,7 @@...@@ -22,6 +21,7 @@
22.global _dataSym21.global _dataSym
23.global _unexported22.global _unexported
24.global __imp__unexported23.global __imp__unexported
24.global .refptr._foobar
25.text25.text
26_DllMainCRTStartup@12:26_DllMainCRTStartup@12:
27 ret27 ret
...@@ -34,6 +34,8 @@ _dataSym:...@@ -34,6 +34,8 @@ _dataSym:
34 .int 434 .int 4
35__imp__unexported:35__imp__unexported:
36 .int _unexported36 .int _unexported
37.refptr._foobar:
38 .int _foobar
3739
38# Test specifying -export-all-symbols, on an object file that contains40# Test specifying -export-all-symbols, on an object file that contains
39# dllexport directive for some of the symbols.41# dllexport directive for some of the symbols.
...@@ -63,6 +65,7 @@ __imp__unexported:...@@ -63,6 +65,7 @@ __imp__unexported:
63# RUN: mkdir -p %T/libs65# RUN: mkdir -p %T/libs
64# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s66# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s
65# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o67# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o
68# RUN: rm -f %T/libs/libmingwex.a
66# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o69# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o
67# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s70# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s
68# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o71# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o
...@@ -74,6 +77,18 @@ __imp__unexported:...@@ -74,6 +77,18 @@ __imp__unexported:
74# CHECK-EXCLUDE-NEXT: foobar @177# CHECK-EXCLUDE-NEXT: foobar @1
75# CHECK-EXCLUDE-NEXT: EOF78# CHECK-EXCLUDE-NEXT: EOF
7679
80# Test that libraries included with -wholearchive: are autoexported, even if
81# they are in a library that otherwise normally would be excluded.
82
83# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o -wholearchive:%T/libs/libmingwex.a -output-def:%t.def
84# RUN: echo "EOF" >> %t.def
85# RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s
86
87# CHECK-WHOLEARCHIVE: EXPORTS
88# CHECK-WHOLEARCHIVE-NEXT: foobar @1
89# CHECK-WHOLEARCHIVE-NEXT: mingwfunc @2
90# CHECK-WHOLEARCHIVE-NEXT: EOF
91
77# Test that we handle import libraries together with -opt:noref.92# Test that we handle import libraries together with -opt:noref.
7893
79# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj94# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
deps/lld/test/COFF/export.test+9
...@@ -97,3 +97,12 @@ FORWARDER: Ordinal RVA Name...@@ -97,3 +97,12 @@ FORWARDER: Ordinal RVA Name
97FORWARDER: 0 097FORWARDER: 0 0
98FORWARDER: 1 0x1010 exportfn98FORWARDER: 1 0x1010 exportfn
99FORWARDER: 2 foo (forwarded to kernel32.foobar)99FORWARDER: 2 foo (forwarded to kernel32.foobar)
100
101# RUN: lld-link /out:%t.dll /dll %t.obj /merge:.rdata=.text /export:exportfn1 /export:exportfn2
102# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=MERGE -match-full-lines %s
103
104MERGE: DLL name: export.test.tmp.dll
105MERGE: Ordinal RVA Name
106MERGE-NEXT: 0 0
107MERGE-NEXT: 1 0x1008 exportfn1
108MERGE-NEXT: 2 0x1010 exportfn2
deps/lld/test/COFF/force-multiple.test created+45
...@@ -0,0 +1,45 @@
1# RUN: yaml2obj < %s > %t1.obj
2# RUN: yaml2obj < %s > %t2.obj
3
4# RUN: not lld-link /out:%t.exe /entry:main %t1.obj %t2.obj >& %t.log
5# RUN: FileCheck -check-prefix=ERROR %s < %t.log
6
7# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force >& %t.log
8# RUN: FileCheck -check-prefix=WARN %s < %t.log
9
10# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force:multiple >& %t.log
11# RUN: FileCheck -check-prefix=WARN %s < %t.log
12
13# ERROR: error: duplicate symbol: main
14
15# WARN: warning: duplicate symbol: main
16
17--- !COFF
18header:
19 Machine: IMAGE_FILE_MACHINE_AMD64
20 Characteristics: []
21sections:
22 - Name: .text
23 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
24 Alignment: 4
25 SectionData: 000000000000
26symbols:
27 - Name: .text
28 Value: 0
29 SectionNumber: 1
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 SectionDefinition:
34 Length: 6
35 NumberOfRelocations: 0
36 NumberOfLinenumbers: 0
37 CheckSum: 0
38 Number: 0
39 - Name: main
40 Value: 0
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_NULL
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45...
deps/lld/test/COFF/gfids-export.s created+44
...@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple x86_64-pc-win32 %s -filetype=obj -o %t.obj
3# RUN: lld-link %t.obj -guard:cf -dll -out:%t.dll -noentry
4# RUN: llvm-readobj -coff-load-config %t.dll | FileCheck %s --check-prefix=CHECK
5
6# There should be a single entry in the table for the exported symbol.
7#
8# CHECK: GuardFidTable [
9# CHECK-NEXT: 0x180001000
10# CHECK-NEXT: ]
11
12 .def func_export; .scl 2; .type 32; .endef
13 .globl func_export
14 .section .text,"xr",one_only,func_export
15 .p2align 4
16func_export:
17 movl $1, %eax
18 .globl label_export
19label_export:
20 movl $2, %eax
21 ret
22
23 .data
24 .globl data_export
25data_export:
26 .long 42
27
28 .section .drectve,"dr"
29 .ascii " /EXPORT:func_export"
30 .ascii " /EXPORT:label_export"
31 .ascii " /EXPORT:data_export"
32
33
34# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY64).
35# The linker will define the __guard_* symbols.
36 .section .rdata,"dr"
37.globl _load_config_used
38_load_config_used:
39 .long 256
40 .fill 124, 1, 0
41 .quad __guard_fids_table
42 .quad __guard_fids_count
43 .long __guard_flags
44 .fill 128, 1, 0
deps/lld/test/COFF/gfids-relocations32.s created+87
...@@ -0,0 +1,87 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple i686-pc-win32 %s -filetype=obj -o %t.obj
3# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main
4# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
5
6# Only f and _main should go in the table.
7# (use /lldmap:map.txt to check their addresses).
8#
9# CHECK: GuardFidTable [
10# CHECK-NEXT: 0x401000
11# CHECK-NEXT: 0x401030
12# CHECK-NEXT: ]
13
14# The input was loosly based on studying this program:
15#
16# void foo() { return; }
17# void bar() { return; }
18# int main() {
19# foo();
20# void (*arr[])() = { &bar };
21# (*arr[0])();
22# return 0;
23# }
24# cl /c a.cc && dumpbin /disasm a.obj > a.txt &&
25# link a.obj /guard:cf /map:map.txt && dumpbin /loadconfig a.exe
26
27
28
29 .def f;
30 .scl 3;
31 .type 32;
32 .endef
33 .section .text,"xr",one_only,f
34 .p2align 4
35f: movl $1, %eax
36 ret
37
38
39 .def g;
40 .scl 3;
41 .type 32;
42 .endef
43 .section .text,"xr",one_only,g
44 .p2align 4
45g: movl $2, %eax
46 ret
47
48
49 .def label;
50 .scl 6; # StorageClass: Label
51 .type 0; # Type: Not a function.
52 .endef
53 .section .text,"xr",one_only,label
54 .p2align 4
55label: ret
56
57
58 .data
59 .globl fp
60 .p2align 4
61fp: .long f # DIR32 relocation to function
62 .long label # DIR32 relocation to label
63
64
65 .def _main;
66 .scl 2;
67 .type 32;
68 .endef
69 .section .text,"xr",one_only,_main
70 .globl _main
71 .p2align 4
72_main: call *fp # DIR32 relocation to data
73 call g # REL32 relocation to function
74 ret
75
76
77# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY32).
78# The linker will define the ___guard_* symbols.
79 .section .rdata,"dr"
80.globl __load_config_used
81__load_config_used:
82 .long 104 # Size.
83 .fill 76, 1, 0
84 .long ___guard_fids_table
85 .long ___guard_fids_count
86 .long ___guard_flags
87 .fill 12, 1, 0
deps/lld/test/COFF/gfids-relocations64.s created+76
...@@ -0,0 +1,76 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple x86_64-pc-win32 %s -filetype=obj -o %t.obj
3# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main
4# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
5
6# f, g, and main go in the table.
7# Including g isn't strictly necessary since it's not an indirect call target,
8# however the linker can't know that because relative relocations are used both
9# for direct calls and for getting the absolute address of a function.
10# (use /lldmap:map.txt to check their addresses).
11#
12# CHECK: GuardFidTable [
13# CHECK-NEXT: 0x140001000
14# CHECK-NEXT: 0x140001010
15# CHECK-NEXT: 0x140001030
16# CHECK-NEXT: ]
17
18 .def f;
19 .scl 3;
20 .type 32;
21 .endef
22 .section .text,"xr",one_only,f
23 .p2align 4
24f: movl $1, %eax
25 ret
26
27
28 .def g;
29 .scl 3;
30 .type 32;
31 .endef
32 .section .text,"xr",one_only,g
33 .p2align 4
34g: movl $2, %eax
35 ret
36
37
38 .def label;
39 .scl 6; # StorageClass: Label
40 .type 0; # Type: Not a function.
41 .endef
42 .section .text,"xr",one_only,label
43 .p2align 4
44label: ret
45
46
47 .data
48 .globl fp
49 .p2align 4
50fp: .quad f # DIR32 relocation to function
51 .quad label # DIR32 relocation to label
52
53
54 .def main;
55 .scl 2;
56 .type 32;
57 .endef
58 .section .text,"xr",one_only,main
59 .globl main
60 .p2align 4
61main: call *fp # DIR32 relocation to data
62 call g # REL32 relocation to function
63 ret
64
65
66# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY64).
67# The linker will define the __guard_* symbols.
68 .section .rdata,"dr"
69.globl _load_config_used
70_load_config_used:
71 .long 256
72 .fill 124, 1, 0
73 .quad __guard_fids_table
74 .quad __guard_fids_count
75 .long __guard_flags
76 .fill 128, 1, 0
deps/lld/test/COFF/gnu-weak.test created+52
...@@ -0,0 +1,52 @@
1RUN: lld-link -lldmingw %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
2
3GNU ld can handle several definitions of the same weak symbol, and
4unless there is a strong definition of it, it just picks the first
5weak definition encountered.
6
7For each of the weak definitions, GNU tools produce a regular symbol
8named .weak.<weaksymbol>.<othersymbol>, where the other symbol name is
9another symbol defined close by.
10
11This can't be reproduced by assembling with llvm-mc, as llvm-mc always
12produces similar regular symbols named .weak.<weaksymbol>.default.
13
14The bundled object files can be produced from test code that looks like
15this:
16
17$ cat gnu-weak.c
18void weakfunc(void) __attribute__((weak));
19void otherfunc(void);
20
21__attribute__((weak)) void weakfunc() {
22}
23
24int main(int argc, char* argv[]) {
25 otherfunc();
26 weakfunc();
27 return 0;
28}
29void mainCRTStartup(void) {
30 main(0, (char**)0);
31}
32void __main(void) {
33}
34
35$ cat gnu-weak2.c
36void weakfunc(void) __attribute__((weak));
37
38__attribute__((weak)) void weakfunc() {
39}
40
41void otherfunc(void) {
42}
43
44$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak.c
45$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak2.c
46
47$ x86_64-w64-mingw32-nm gnu-weak.o | grep weakfunc
480000000000000000 T .weak.weakfunc.main
49 w weakfunc
50$ x86_64-w64-mingw32-nm gnu-weak2.o | grep weakfunc
510000000000000000 T .weak.weakfunc.otherfunc
52 w weakfunc
deps/lld/test/COFF/header-size.s created+12
...@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
3// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe
4// RUN: llvm-readobj -sections %t.exe | FileCheck %s
5 .globl main
6main:
7 ret
8
9// Check that the first section data comes at 512 bytes in the file.
10// If the size allocated for headers would include size for section
11// headers which aren't written, PointerToRawData would be 0x400 instead.
12// CHECK: PointerToRawData: 0x200
deps/lld/test/COFF/icf-safe.s created+37
...@@ -0,0 +1,37 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o %t1.obj
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %S/Inputs/icf-safe.s -o %t2.obj
4# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf %t1.obj %t2.obj 2>&1 | FileCheck %s
5# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf /export:g3 /export:g4 %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=EXPORT %s
6
7# CHECK-NOT: Selected
8# CHECK: Selected g3
9# CHECK-NEXT: Removed g4
10# CHECK-NOT: Removed
11# CHECK-NOT: Selected
12
13# EXPORT-NOT: Selected
14
15.section .rdata,"dr",one_only,g1
16.globl g1
17g1:
18.byte 1
19
20.section .rdata,"dr",one_only,g2
21.globl g2
22g2:
23.byte 1
24
25.section .rdata,"dr",one_only,g3
26.globl g3
27g3:
28.byte 2
29
30.section .rdata,"dr",one_only,g4
31.globl g4
32g4:
33.byte 2
34
35.addrsig
36.addrsig_sym g1
37.addrsig_sym g2
deps/lld/test/COFF/ignore-many.test created+16
...@@ -0,0 +1,16 @@
1Tests /ignore with more than one argument.
2
3RUN: yaml2obj %S/ignore4217.yaml > %t1.obj
4RUN: yaml2obj %S/Inputs/pdb-type-server-missing-2.yaml > %t2.obj
5RUN: echo foo > %t3.order
6
7RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug 2>&1 | FileCheck -check-prefix=WARNINGS %s
8RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug /ignore:4217,4099,4037 2>&1 | FileCheck -allow-empty -check-prefix=SUPPRESSED %s
9
10WARNINGS: locally defined symbol imported
11WARNINGS: missing symbol: foo
12WARNINGS: warning: Cannot use debug info for
13
14SUPPRESSED-NOT: locally defined symbol imported
15SUPPRESSED-NOT: missing symbol: foo
16SUPPRESSED-NOT: warning: Cannot use debug info for
deps/lld/test/COFF/imports-gnu-autoexport.s created+25
...@@ -0,0 +1,25 @@
1# REQUIRES: x86
2#
3# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
4# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
5# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
6# RUN: rm -f %t-implib.a
7# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
8# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main -subsystem:console \
9# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib %t-implib.a -include:func
10# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix=EXPORT %s
11
12# Check that only the single normal symbol was exported, none of the symbols
13# from the import library.
14
15EXPORT: Export {
16EXPORT-NEXT: Ordinal: 0
17EXPORT-NEXT: Name:
18EXPORT-NEXT: RVA: 0x0
19EXPORT-NEXT: }
20EXPORT-NEXT: Export {
21EXPORT-NEXT: Ordinal: 1
22EXPORT-NEXT: Name: main
23EXPORT-NEXT: RVA: 0x1010
24EXPORT-NEXT: }
25EXPORT-NEXT-EMPTY:
deps/lld/test/COFF/imports-gnu-only.s created+28
...@@ -0,0 +1,28 @@
1# REQUIRES: x86
2#
3# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
4# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
5# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
6# RUN: rm -f %t-implib.a
7# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
8# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
9# RUN: lld-link -out:%t.exe -entry:main -subsystem:console \
10# RUN: %t.obj %t-implib.a
11# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DATA %s
12
13 .text
14 .global main
15main:
16 call func
17 ret
18
19# Check that the linker inserted the null terminating import descriptor,
20# even if there were no normal import libraries, only gnu ones.
21
22# DATA: Contents of section .rdata:
23# First import descriptor
24# DATA: 140002000 28200000 00000000 00000000 53200000
25# Last word from first import descriptor, null terminator descriptor
26# DATA: 140002010 38200000 00000000 00000000 00000000
27# Null terminator descriptor and import lookup table.
28# DATA: 140002020 00000000 00000000 48200000 00000000
deps/lld/test/COFF/imports-gnu.test created+29
...@@ -0,0 +1,29 @@
1# REQUIRES: x86
2# Verify that the lld can link to GNU import libs.
3#
4# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
5# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
6# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
7# RUN: rm -f %t-implib.a
8# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
9# Not linking with -lldmingw; one can link to GNU import libs even if not targeting MinGW.
10# RUN: lld-link -out:%t.exe -entry:main -subsystem:console \
11# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib %t-implib.a -include:func
12# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
13
14# Check that import entries from both libraries show up.
15
16IMPORT: Import {
17IMPORT-NEXT: Name: foo.dll
18IMPORT-NEXT: ImportLookupTableRVA:
19IMPORT-NEXT: ImportAddressTableRVA:
20IMPORT-NEXT: Symbol: func (0)
21IMPORT-NEXT: }
22IMPORT-NEXT: Import {
23IMPORT-NEXT: Name: std64.dll
24IMPORT-NEXT: ImportLookupTableRVA:
25IMPORT-NEXT: ImportAddressTableRVA:
26IMPORT-NEXT: Symbol: ExitProcess (0)
27IMPORT-NEXT: Symbol: (50)
28IMPORT-NEXT: Symbol: MessageBoxA (1)
29IMPORT-NEXT: }
deps/lld/test/COFF/imports.test+13
...@@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0)...@@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0)
34IMPORT-NEXT: Symbol: (50)34IMPORT-NEXT: Symbol: (50)
35IMPORT-NEXT: Symbol: MessageBoxA (1)35IMPORT-NEXT: Symbol: MessageBoxA (1)
36IMPORT-NEXT: }36IMPORT-NEXT: }
37
38# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \
39# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
40# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s
41
42MERGE: Import {
43MERGE-NEXT: Name: std64.dll
44MERGE-NEXT: ImportLookupTableRVA: 0x1090
45MERGE-NEXT: ImportAddressTableRVA: 0x10B0
46MERGE-NEXT: Symbol: ExitProcess (0)
47MERGE-NEXT: Symbol: (50)
48MERGE-NEXT: Symbol: MessageBoxA (1)
49MERGE-NEXT: }
deps/lld/test/COFF/invalid-debug-type.test+2-1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \3# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj4# RUN: %t1.obj %t2.obj 2>&1 | FileCheck %s
55
6# CHECK: /debugtype: unknown option: invalid
\ No newline at end of file
deps/lld/test/COFF/invalid-debug.test created+6
...@@ -0,0 +1,6 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: not lld-link /debug /debug:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj 2>&1 | FileCheck %s
5
6# CHECK: /debug: unknown option: invalid
deps/lld/test/COFF/libname-mingw.test created+8
...@@ -0,0 +1,8 @@
1# RUN: mkdir -p %t/a
2# RUN: cp %p/Inputs/std64.lib %t/a/libstd64.a
3
4# RUN: lld-link /lldmingw /out:%t.exe /entry:main /verbose \
5# RUN: /defaultlib:std64.lib /subsystem:console %p/Inputs/hello64.obj \
6# RUN: /libpath:%t/a 2>&1 | FileCheck %s
7
8CHECK: a{{[/\\]}}libstd64.a
deps/lld/test/COFF/line-error.yaml created+160
...@@ -0,0 +1,160 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: not lld-link %t.obj /subsystem:console 2>&1 | FileCheck %s
3
4# CHECK: lld-link: error: undefined symbol: function
5# CHECK-NEXT: >>> referenced by {{.*}}line-error.yaml.tmp.obj:(caller1)
6# CHECK-NEXT: >>> referenced by E:\file.cpp:1935
7# CHECK-NEXT: >>> {{.*}}line-error.yaml.tmp.obj:(caller22)
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: [ ]
13sections:
14 - Name: .text
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 488B0500000000488B51284881C2D80000004889C148FF2500000000
18 Relocations:
19 - VirtualAddress: 3
20 SymbolName: function
21 Type: IMAGE_REL_AMD64_REL32
22 - Name: .text
23 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
24 Alignment: 16
25 SectionData: 488B0500000000488B51084881C2D80000004889C148FF2500000000
26 Relocations:
27 - VirtualAddress: 3
28 SymbolName: function
29 Type: IMAGE_REL_AMD64_REL32
30 - Name: '.debug$S'
31 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
32 Alignment: 4
33 Subsections:
34 - !FileChecksums
35 Checksums:
36 - FileName: 'E:\file.cpp'
37 Kind: MD5
38 Checksum: D72EDEF8B8E50C364A330F9CB3CD904B
39 - !StringTable
40 Strings:
41 - 'E:\file.cpp'
42 - Name: '.debug$S'
43 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
44 Alignment: 4
45 Subsections:
46 - !Lines
47 CodeSize: 28
48 Flags: [ ]
49 RelocOffset: 0
50 RelocSegment: 0
51 Blocks: []
52 Relocations:
53 - VirtualAddress: 12
54 SymbolName: caller1
55 Type: IMAGE_REL_AMD64_SECREL
56 - Name: '.debug$S'
57 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
58 Alignment: 4
59 Subsections:
60 - !Lines
61 CodeSize: 28
62 Flags: [ ]
63 RelocOffset: 0
64 RelocSegment: 0
65 Blocks:
66 - FileName: 'E:\file.cpp'
67 Lines:
68 - Offset: 11
69 LineStart: 1935
70 IsStatement: false
71 EndDelta: 0
72 Columns: []
73 Relocations:
74 - VirtualAddress: 12
75 SymbolName: caller22
76 Type: IMAGE_REL_AMD64_SECREL
77symbols:
78 - Name: .text
79 Value: 0
80 SectionNumber: 1
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_STATIC
84 SectionDefinition:
85 Length: 28
86 NumberOfRelocations: 2
87 NumberOfLinenumbers: 0
88 CheckSum: 2430089736
89 Number: 1
90 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
91 - Name: caller1
92 Value: 0
93 SectionNumber: 1
94 SimpleType: IMAGE_SYM_TYPE_NULL
95 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
96 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
97 - Name: .text
98 Value: 0
99 SectionNumber: 2
100 SimpleType: IMAGE_SYM_TYPE_NULL
101 ComplexType: IMAGE_SYM_DTYPE_NULL
102 StorageClass: IMAGE_SYM_CLASS_STATIC
103 SectionDefinition:
104 Length: 28
105 NumberOfRelocations: 2
106 NumberOfLinenumbers: 0
107 CheckSum: 3449717304
108 Number: 2
109 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
110 - Name: caller22
111 Value: 0
112 SectionNumber: 2
113 SimpleType: IMAGE_SYM_TYPE_NULL
114 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
115 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
116 - Name: '.debug$S'
117 Value: 0
118 SectionNumber: 3
119 SimpleType: IMAGE_SYM_TYPE_NULL
120 ComplexType: IMAGE_SYM_DTYPE_NULL
121 StorageClass: IMAGE_SYM_CLASS_STATIC
122 SectionDefinition:
123 Length: 767204
124 NumberOfRelocations: 0
125 NumberOfLinenumbers: 0
126 CheckSum: 4280093374
127 Number: 3
128 - Name: '.debug$S'
129 Value: 0
130 SectionNumber: 4
131 SimpleType: IMAGE_SYM_TYPE_NULL
132 ComplexType: IMAGE_SYM_DTYPE_NULL
133 StorageClass: IMAGE_SYM_CLASS_STATIC
134 SectionDefinition:
135 Length: 296
136 NumberOfRelocations: 1
137 NumberOfLinenumbers: 0
138 CheckSum: 1957793731
139 Number: 1
140 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
141 - Name: '.debug$S'
142 Value: 0
143 SectionNumber: 5
144 SimpleType: IMAGE_SYM_TYPE_NULL
145 ComplexType: IMAGE_SYM_DTYPE_NULL
146 StorageClass: IMAGE_SYM_CLASS_STATIC
147 SectionDefinition:
148 Length: 276
149 NumberOfRelocations: 1
150 NumberOfLinenumbers: 0
151 CheckSum: 1957793731
152 Number: 2
153 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
154 - Name: function
155 Value: 0
156 SectionNumber: 0
157 SimpleType: IMAGE_SYM_TYPE_NULL
158 ComplexType: IMAGE_SYM_DTYPE_NULL
159 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
160...
deps/lld/test/COFF/lto-cache.ll+2
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1; REQUIRES: x861; REQUIRES: x86
2; NetBSD: noatime mounts currently inhibit 'touch' from updating atime
3; UNSUPPORTED: system-netbsd
24
3; RUN: opt -module-hash -module-summary %s -o %t.o5; RUN: opt -module-hash -module-summary %s -o %t.o
4; RUN: opt -module-hash -module-summary %p/Inputs/lto-cache.ll -o %t2.o6; RUN: opt -module-hash -module-summary %p/Inputs/lto-cache.ll -o %t2.o
deps/lld/test/COFF/lto-chkstk.ll+1
...@@ -2,6 +2,7 @@...@@ -2,6 +2,7 @@
2; RUN: llvm-as -o %t.obj %s2; RUN: llvm-as -o %t.obj %s
3; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s3; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s
4; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s4; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s
5; RUN: rm -f %t.lib
5; RUN: llvm-ar cru %t.lib %T/lto-chkstk-chkstk.obj6; RUN: llvm-ar cru %t.lib %T/lto-chkstk-chkstk.obj
6; RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj %T/lto-chkstk-foo.obj %t.lib7; RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj %T/lto-chkstk-foo.obj %t.lib
78
deps/lld/test/COFF/lto-cpu-string.ll created+21
...@@ -0,0 +1,21 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.obj
3
4; RUN: lld-link %t.obj -noentry -nodefaultlib -out:%t.dll -dll
5; RUN: llvm-objdump -d -section=".text" -no-leading-addr -no-show-raw-insn %t.dll | FileCheck %s
6; CHECK: nop{{$}}
7
8; RUN: lld-link -mllvm:-mcpu=znver1 -noentry -nodefaultlib %t.obj -out:%t.znver1.dll -dll
9; RUN: llvm-objdump -d -section=".text" -no-leading-addr -no-show-raw-insn %t.znver1.dll | FileCheck -check-prefix=ZNVER1 %s
10; ZNVER1: nopw
11
12target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
13target triple = "x86_64-pc-windows-msvc19.14.26433"
14
15define dllexport void @foo() #0 {
16entry:
17 call void asm sideeffect ".p2align 4, 0x90", "~{dirflag},~{fpsr},~{flags}"()
18 ret void
19}
20
21attributes #0 = { "no-frame-pointer-elim"="true" }
deps/lld/test/COFF/msvclto-archive.ll deleted-40
...@@ -1,40 +0,0 @@
1; REQUIRES: x86
2;; Make sure we re-create archive files to strip bitcode files.
3
4;; Do not create empty archives because the MSVC linker
5;; doesn't support them.
6; RUN: llvm-as -o %t.obj %s
7; RUN: rm -f %t-main1.a
8; RUN: llvm-ar cru %t-main1.a %t.obj
9; RUN: mkdir -p %t.dir
10; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
11; RUN: lld-link %t-main1.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
12; RUN: /entry:main /verbose 2> %t.log || true
13; RUN: FileCheck -check-prefix=BC %s < %t.log
14; BC-NOT: Creating a temporary archive for
15
16; RUN: rm -f %t-main2.a
17; RUN: llvm-ar cru %t-main2.a %t.dir/bitcode.obj
18; RUN: lld-link %t.obj %t-main2.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
19; RUN: /entry:main /verbose 2> %t.log || true
20; RUN: FileCheck -check-prefix=OBJ %s < %t.log
21; OBJ-NOT: Creating a temporary archive
22
23;; Make sure that we always rebuild thin archives because
24;; the MSVC linker doesn't support thin archives.
25; RUN: rm -f %t-main3.a
26; RUN: llvm-ar cruT %t-main3.a %t.dir/bitcode.obj
27; RUN: lld-link %t.obj %t-main3.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
28; RUN: /entry:main /verbose 2> %t.log || true
29; RUN: FileCheck -check-prefix=THIN %s < %t.log
30; THIN: Creating a temporary archive
31
32target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
33target triple = "x86_64-pc-windows-msvc"
34
35declare void @foo()
36
37define i32 @main() {
38 call void @foo()
39 ret i32 0
40}
deps/lld/test/COFF/msvclto-order.ll deleted-25
...@@ -1,25 +0,0 @@
1; REQUIRES: x86
2; RUN: opt -thinlto-bc %s -o %t.obj
3; RUN: llc -filetype=obj %S/Inputs/msvclto-order-a.ll -o %T/msvclto-order-a.obj
4; RUN: llvm-ar crs %T/msvclto-order-a.lib %T/msvclto-order-a.obj
5; RUN: llc -filetype=obj %S/Inputs/msvclto-order-b.ll -o %T/msvclto-order-b.obj
6; RUN: llvm-ar crs %T/msvclto-order-b.lib %T/msvclto-order-b.obj
7; RUN: lld-link /verbose /msvclto /out:%t.exe /entry:main %t.obj \
8; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib 2> %t.log || true
9; RUN: FileCheck %s < %t.log
10
11; CHECK: : link.exe
12; CHECK-NOT: .lib{{$}}
13; CHECK: lld-msvclto-order-a{{.*}}.obj
14; CHECK-NOT: lld-msvclto-order-b{{.*}}.obj
15; CHECK: .lib{{$}}
16
17target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
18target triple = "x86_64-pc-windows-msvc"
19
20declare void @foo()
21
22define i32 @main() {
23 call void @foo()
24 ret i32 0
25}
deps/lld/test/COFF/msvclto.ll deleted-20
...@@ -1,20 +0,0 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.obj %s
3; RUN: mkdir -p %t.dir
4; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
5; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
6; RUN: /entry:main /verbose 2> %t.log || true
7; RUN: FileCheck %s < %t.log
8
9; CHECK: /opt:icf /entry:main
10; CHECK: /verbose
11
12target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
13target triple = "x86_64-pc-windows-msvc"
14
15declare void @foo()
16
17define i32 @main() {
18 call void @foo()
19 ret i32 0
20}
deps/lld/test/COFF/no-idata.s created+20
...@@ -0,0 +1,20 @@
1# REQUIRES: x86
2#
3# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
4# RUN: lld-link -out:%t.exe -entry:main -subsystem:console %t.obj
5# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DUMP %s
6# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DIRECTORY %s
7
8 .text
9 .global main
10main:
11 ret
12
13# Check that no .idata (.rdata) entries were added, no null terminator
14# for the import descriptor table.
15# DUMP: Contents of section .text:
16# DUMP-NEXT: 140001000 c3
17# DUMP-NEXT-EMPTY:
18
19# DIRECTORY: ImportTableRVA: 0x0
20# DIRECTORY: ImportTableSize: 0x0
deps/lld/test/COFF/pdb-debug-f.s created+28
...@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple=i386-pc-win32 -filetype=obj -o %t.obj %s
3# RUN: lld-link /subsystem:console /debug /nodefaultlib /entry:foo /out:%t.exe /pdb:%t.pdb %t.obj
4# RUN: llvm-pdbutil dump -fpo %t.pdb | FileCheck %s
5
6# CHECK: Old FPO Data
7# CHECK-NEXT: ============================================================
8# CHECK-NEXT: RVA | Code | Locals | Params | Prolog | Saved Regs | Use BP | Has SEH | Frame Type
9# CHECK-NEXT: 00001002 | 1 | 2 | 3 | 4 | 0 | false | false | FPO
10
11.text
12_foo:
13ret
14
15.global _foo
16
17.section .debug$F,"dr"
18 .long _foo@IMGREL+2
19 .long 1 # cbProc
20 .long 2 # cdwLocals;
21 .short 3 # cdwParams;
22 .short 4 # flags
23 # cbProlog : 8;
24 # cbRegs : 3;
25 # fHasSEH : 1;
26 # fUseBP : 1;
27 # reserved : 1;
28 # cbFrame : 2;
\ No newline at end of file
deps/lld/test/COFF/pdb-framedata.yaml created+462
...@@ -0,0 +1,462 @@
1# // Compile with clang-cl -m32 /Z7 /GS- /c t.obj pdb-framedata.cpp
2#
3# int func(int x, int y) {
4# return x + y;
5# }
6#
7# int main(int argc, char **argv) {
8# return func(argc, argc+1);
9# }
10
11# RUN: yaml2obj %s -o %t.obj
12# RUN: lld-link %t.obj -debug -entry:main -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb
13# RUN: llvm-pdbutil dump -fpo %t.pdb | FileCheck %s
14
15# CHECK: New FPO Data
16# CHECK-NEXT: ============================================================
17# CHECK-NEXT: RVA | Code | Locals | Params | Stack | Prolog | Saved Regs | Has SEH | Has C++EH | Start | Program
18# CHECK-NEXT: 00001000 | 31 | 0 | 8 | 0 | 6 | 0 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + =
19# CHECK-NEXT: 00001001 | 30 | 0 | 8 | 0 | 5 | 4 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
20# CHECK-NEXT: 00001003 | 28 | 0 | 8 | 0 | 3 | 4 | false | false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
21# CHECK-NEXT: 00001020 | 53 | 0 | 8 | 0 | 7 | 0 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + =
22# CHECK-NEXT: 00001021 | 52 | 0 | 8 | 0 | 6 | 4 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
23# CHECK-NEXT: 00001023 | 50 | 0 | 8 | 0 | 4 | 4 | false | false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
24# CHECK-NEXT: 00001024 | 49 | 0 | 8 | 0 | 3 | 8 | false | false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ =
25
26
27--- !COFF
28header:
29 Machine: IMAGE_FILE_MACHINE_I386
30 Characteristics: [ ]
31sections:
32 - Name: .text
33 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
34 Alignment: 16
35 SectionData: 5589E583EC088B450C8B4D088B550803550C8945FC89D0894DF883C4085DC3905589E55683EC148B450C8B4D08C745F8000000008B550883C2018B7508893424895424048945F4894DF0E80000000083C4145E5DC3
36 Relocations:
37 - VirtualAddress: 75
38 SymbolName: '?func@@YAHHH@Z'
39 Type: IMAGE_REL_I386_REL32
40 - Name: .data
41 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
42 Alignment: 4
43 SectionData: ''
44 - Name: .bss
45 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
46 Alignment: 4
47 SectionData: ''
48 - Name: .drectve
49 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
50 Alignment: 1
51 SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962
52 - Name: '.debug$S'
53 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
54 Alignment: 4
55 Subsections:
56 - !Symbols
57 Records:
58 - Kind: S_COMPILE3
59 Compile3Sym:
60 Flags: [ ]
61 Machine: Pentium3
62 FrontendMajor: 8
63 FrontendMinor: 0
64 FrontendBuild: 0
65 FrontendQFE: 0
66 BackendMajor: 8000
67 BackendMinor: 0
68 BackendBuild: 0
69 BackendQFE: 0
70 Version: 'clang version 8.0.0 '
71 - !FrameData
72 Frames:
73 - CodeSize: 31
74 FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
75 LocalSize: 0
76 MaxStackSize: 0
77 ParamsSize: 8
78 PrologSize: 6
79 RvaStart: 0
80 SavedRegsSize: 0
81 - CodeSize: 30
82 FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
83 LocalSize: 0
84 MaxStackSize: 0
85 ParamsSize: 8
86 PrologSize: 5
87 RvaStart: 1
88 SavedRegsSize: 4
89 - CodeSize: 28
90 FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
91 LocalSize: 0
92 MaxStackSize: 0
93 ParamsSize: 8
94 PrologSize: 3
95 RvaStart: 3
96 SavedRegsSize: 4
97 - !Symbols
98 Records:
99 - Kind: S_GPROC32_ID
100 ProcSym:
101 CodeSize: 31
102 DbgStart: 0
103 DbgEnd: 0
104 FunctionType: 4098
105 Flags: [ ]
106 DisplayName: func
107 - Kind: S_LOCAL
108 LocalSym:
109 Type: 116
110 Flags: [ IsParameter ]
111 VarName: x
112 - Kind: S_DEFRANGE_REGISTER_REL
113 DefRangeRegisterRelSym:
114 Register: 22
115 Flags: 0
116 BasePointerOffset: 8
117 Range:
118 OffsetStart: 12
119 ISectStart: 0
120 Range: 19
121 Gaps:
122 - Kind: S_LOCAL
123 LocalSym:
124 Type: 116
125 Flags: [ IsParameter ]
126 VarName: y
127 - Kind: S_DEFRANGE_REGISTER_REL
128 DefRangeRegisterRelSym:
129 Register: 22
130 Flags: 0
131 BasePointerOffset: 12
132 Range:
133 OffsetStart: 12
134 ISectStart: 0
135 Range: 19
136 Gaps:
137 - Kind: S_PROC_ID_END
138 ScopeEndSym:
139 - !Lines
140 CodeSize: 31
141 Flags: [ ]
142 RelocOffset: 0
143 RelocSegment: 0
144 Blocks:
145 - FileName: 'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
146 Lines:
147 - Offset: 0
148 LineStart: 3
149 IsStatement: false
150 EndDelta: 0
151 - Offset: 12
152 LineStart: 4
153 IsStatement: false
154 EndDelta: 0
155 Columns:
156 - !FrameData
157 Frames:
158 - CodeSize: 53
159 FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
160 LocalSize: 0
161 MaxStackSize: 0
162 ParamsSize: 8
163 PrologSize: 7
164 RvaStart: 0
165 SavedRegsSize: 0
166 - CodeSize: 52
167 FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
168 LocalSize: 0
169 MaxStackSize: 0
170 ParamsSize: 8
171 PrologSize: 6
172 RvaStart: 1
173 SavedRegsSize: 4
174 - CodeSize: 50
175 FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
176 LocalSize: 0
177 MaxStackSize: 0
178 ParamsSize: 8
179 PrologSize: 4
180 RvaStart: 3
181 SavedRegsSize: 4
182 - CodeSize: 49
183 FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
184 LocalSize: 0
185 MaxStackSize: 0
186 ParamsSize: 8
187 PrologSize: 3
188 RvaStart: 4
189 SavedRegsSize: 8
190 - !Symbols
191 Records:
192 - Kind: S_GPROC32_ID
193 ProcSym:
194 CodeSize: 53
195 DbgStart: 0
196 DbgEnd: 0
197 FunctionType: 4102
198 Flags: [ ]
199 DisplayName: main
200 - Kind: S_LOCAL
201 LocalSym:
202 Type: 116
203 Flags: [ IsParameter ]
204 VarName: argc
205 - Kind: S_DEFRANGE_REGISTER_REL
206 DefRangeRegisterRelSym:
207 Register: 22
208 Flags: 0
209 BasePointerOffset: 8
210 Range:
211 OffsetStart: 52
212 ISectStart: 0
213 Range: 33
214 Gaps:
215 - Kind: S_LOCAL
216 LocalSym:
217 Type: 4099
218 Flags: [ IsParameter ]
219 VarName: argv
220 - Kind: S_DEFRANGE_REGISTER_REL
221 DefRangeRegisterRelSym:
222 Register: 22
223 Flags: 0
224 BasePointerOffset: 12
225 Range:
226 OffsetStart: 52
227 ISectStart: 0
228 Range: 33
229 Gaps:
230 - Kind: S_PROC_ID_END
231 ScopeEndSym:
232 - !Lines
233 CodeSize: 53
234 Flags: [ ]
235 RelocOffset: 0
236 RelocSegment: 0
237 Blocks:
238 - FileName: 'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
239 Lines:
240 - Offset: 0
241 LineStart: 7
242 IsStatement: false
243 EndDelta: 0
244 - Offset: 20
245 LineStart: 8
246 IsStatement: false
247 EndDelta: 0
248 Columns:
249 - !FileChecksums
250 Checksums:
251 - FileName: 'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
252 Kind: MD5
253 Checksum: A611B73E19B77B02646FAAF7CAEB025D
254 - !StringTable
255 Strings:
256 - 'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
257 - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
258 - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
259 - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
260 - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
261 - ''
262 Relocations:
263 - VirtualAddress: 68
264 SymbolName: '?func@@YAHHH@Z'
265 Type: IMAGE_REL_I386_DIR32NB
266 - VirtualAddress: 208
267 SymbolName: '?func@@YAHHH@Z'
268 Type: IMAGE_REL_I386_SECREL
269 - VirtualAddress: 212
270 SymbolName: '?func@@YAHHH@Z'
271 Type: IMAGE_REL_I386_SECTION
272 - VirtualAddress: 244
273 SymbolName: .text
274 Type: IMAGE_REL_I386_SECREL
275 - VirtualAddress: 248
276 SymbolName: .text
277 Type: IMAGE_REL_I386_SECTION
278 - VirtualAddress: 276
279 SymbolName: .text
280 Type: IMAGE_REL_I386_SECREL
281 - VirtualAddress: 280
282 SymbolName: .text
283 Type: IMAGE_REL_I386_SECTION
284 - VirtualAddress: 296
285 SymbolName: '?func@@YAHHH@Z'
286 Type: IMAGE_REL_I386_SECREL
287 - VirtualAddress: 300
288 SymbolName: '?func@@YAHHH@Z'
289 Type: IMAGE_REL_I386_SECTION
290 - VirtualAddress: 344
291 SymbolName: _main
292 Type: IMAGE_REL_I386_DIR32NB
293 - VirtualAddress: 516
294 SymbolName: _main
295 Type: IMAGE_REL_I386_SECREL
296 - VirtualAddress: 520
297 SymbolName: _main
298 Type: IMAGE_REL_I386_SECTION
299 - VirtualAddress: 555
300 SymbolName: .text
301 Type: IMAGE_REL_I386_SECREL
302 - VirtualAddress: 559
303 SymbolName: .text
304 Type: IMAGE_REL_I386_SECTION
305 - VirtualAddress: 590
306 SymbolName: .text
307 Type: IMAGE_REL_I386_SECREL
308 - VirtualAddress: 594
309 SymbolName: .text
310 Type: IMAGE_REL_I386_SECTION
311 - VirtualAddress: 612
312 SymbolName: _main
313 Type: IMAGE_REL_I386_SECREL
314 - VirtualAddress: 616
315 SymbolName: _main
316 Type: IMAGE_REL_I386_SECTION
317 - Name: '.debug$T'
318 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
319 Alignment: 4
320 Types:
321 - Kind: LF_ARGLIST
322 ArgList:
323 ArgIndices: [ 116, 116 ]
324 - Kind: LF_PROCEDURE
325 Procedure:
326 ReturnType: 116
327 CallConv: NearC
328 Options: [ None ]
329 ParameterCount: 2
330 ArgumentList: 4096
331 - Kind: LF_FUNC_ID
332 FuncId:
333 ParentScope: 0
334 FunctionType: 4097
335 Name: func
336 - Kind: LF_POINTER
337 Pointer:
338 ReferentType: 1136
339 Attrs: 32778
340 - Kind: LF_ARGLIST
341 ArgList:
342 ArgIndices: [ 116, 4099 ]
343 - Kind: LF_PROCEDURE
344 Procedure:
345 ReturnType: 116
346 CallConv: NearC
347 Options: [ None ]
348 ParameterCount: 2
349 ArgumentList: 4100
350 - Kind: LF_FUNC_ID
351 FuncId:
352 ParentScope: 0
353 FunctionType: 4101
354 Name: main
355 - Name: .llvm_addrsig
356 Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
357 Alignment: 1
358 SectionData: 0F
359symbols:
360 - Name: .text
361 Value: 0
362 SectionNumber: 1
363 SimpleType: IMAGE_SYM_TYPE_NULL
364 ComplexType: IMAGE_SYM_DTYPE_NULL
365 StorageClass: IMAGE_SYM_CLASS_STATIC
366 SectionDefinition:
367 Length: 85
368 NumberOfRelocations: 1
369 NumberOfLinenumbers: 0
370 CheckSum: 1989857796
371 Number: 1
372 - Name: .data
373 Value: 0
374 SectionNumber: 2
375 SimpleType: IMAGE_SYM_TYPE_NULL
376 ComplexType: IMAGE_SYM_DTYPE_NULL
377 StorageClass: IMAGE_SYM_CLASS_STATIC
378 SectionDefinition:
379 Length: 0
380 NumberOfRelocations: 0
381 NumberOfLinenumbers: 0
382 CheckSum: 0
383 Number: 2
384 - Name: .bss
385 Value: 0
386 SectionNumber: 3
387 SimpleType: IMAGE_SYM_TYPE_NULL
388 ComplexType: IMAGE_SYM_DTYPE_NULL
389 StorageClass: IMAGE_SYM_CLASS_STATIC
390 SectionDefinition:
391 Length: 0
392 NumberOfRelocations: 0
393 NumberOfLinenumbers: 0
394 CheckSum: 0
395 Number: 3
396 - Name: .drectve
397 Value: 0
398 SectionNumber: 4
399 SimpleType: IMAGE_SYM_TYPE_NULL
400 ComplexType: IMAGE_SYM_DTYPE_NULL
401 StorageClass: IMAGE_SYM_CLASS_STATIC
402 SectionDefinition:
403 Length: 48
404 NumberOfRelocations: 0
405 NumberOfLinenumbers: 0
406 CheckSum: 149686238
407 Number: 4
408 - Name: '.debug$S'
409 Value: 0
410 SectionNumber: 5
411 SimpleType: IMAGE_SYM_TYPE_NULL
412 ComplexType: IMAGE_SYM_DTYPE_NULL
413 StorageClass: IMAGE_SYM_CLASS_STATIC
414 SectionDefinition:
415 Length: 988
416 NumberOfRelocations: 18
417 NumberOfLinenumbers: 0
418 CheckSum: 2571438511
419 Number: 5
420 - Name: '.debug$T'
421 Value: 0
422 SectionNumber: 6
423 SimpleType: IMAGE_SYM_TYPE_NULL
424 ComplexType: IMAGE_SYM_DTYPE_NULL
425 StorageClass: IMAGE_SYM_CLASS_STATIC
426 SectionDefinition:
427 Length: 120
428 NumberOfRelocations: 0
429 NumberOfLinenumbers: 0
430 CheckSum: 3148269371
431 Number: 6
432 - Name: .llvm_addrsig
433 Value: 0
434 SectionNumber: 7
435 SimpleType: IMAGE_SYM_TYPE_NULL
436 ComplexType: IMAGE_SYM_DTYPE_NULL
437 StorageClass: IMAGE_SYM_CLASS_STATIC
438 SectionDefinition:
439 Length: 1
440 NumberOfRelocations: 0
441 NumberOfLinenumbers: 0
442 CheckSum: 2428444049
443 Number: 7
444 - Name: '@feat.00'
445 Value: 1
446 SectionNumber: -1
447 SimpleType: IMAGE_SYM_TYPE_NULL
448 ComplexType: IMAGE_SYM_DTYPE_NULL
449 StorageClass: IMAGE_SYM_CLASS_STATIC
450 - Name: '?func@@YAHHH@Z'
451 Value: 0
452 SectionNumber: 1
453 SimpleType: IMAGE_SYM_TYPE_NULL
454 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
455 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
456 - Name: _main
457 Value: 32
458 SectionNumber: 1
459 SimpleType: IMAGE_SYM_TYPE_NULL
460 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
461 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
462...
deps/lld/test/COFF/pdb-global-hashes.test+3-3
...@@ -4,9 +4,9 @@ RUN: yaml2obj %p/Inputs/pdb-hashes-2-missing.yaml > %t.2.missing.obj...@@ -4,9 +4,9 @@ RUN: yaml2obj %p/Inputs/pdb-hashes-2-missing.yaml > %t.2.missing.obj
4RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb4RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb
5RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb5RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb
6RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb6RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb
7RUN: llvm-pdbutil dump -types -ids %t.nohash.pdb | FileCheck %s7RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.nohash.pdb | FileCheck %s
8RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s8RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.hash.pdb | FileCheck %s
9RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s9RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.mixed.pdb | FileCheck %s
1010
11; These object files were generated via the following inputs and commands:11; These object files were generated via the following inputs and commands:
12; ----------------------------------------------12; ----------------------------------------------
deps/lld/test/COFF/pdb-globals.test+5-1
...@@ -15,6 +15,8 @@ RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s...@@ -15,6 +15,8 @@ RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
15CHECK-LABEL: Global Symbols15CHECK-LABEL: Global Symbols
16CHECK-NEXT: ============================================================16CHECK-NEXT: ============================================================
17CHECK-NEXT: Records17CHECK-NEXT: Records
18CHECK-NEXT: 340 | S_UDT [size = 20] `HelloPoint`
19CHECK-NEXT: original type = 0x1007
18CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc`20CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc`
19CHECK-NEXT: module = 1, sum name = 0, offset = 29221CHECK-NEXT: module = 1, sum name = 0, offset = 292
20CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc`22CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc`
...@@ -25,9 +27,11 @@ CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall`...@@ -25,9 +27,11 @@ CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall`
25CHECK-NEXT: type = 0x0403 (void*), addr = 0003:000427CHECK-NEXT: type = 0x0403 (void*), addr = 0003:0004
26CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar`28CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar`
27CHECK-NEXT: type = 0x100B (const int*), addr = 0003:000029CHECK-NEXT: type = 0x100B (const int*), addr = 0003:0000
30CHECK-NEXT: 312 | S_UDT [size = 28] `HelloPointTypedef`
31CHECK-NEXT: original type = 0x1005
28CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar`32CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar`
29CHECK-NEXT: type = 0x100A (const int), addr = 0002:000033CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000
30CHECK-NEXT: 312 | S_PROCREF [size = 40] `HelloPoint::HelloPoint`34CHECK-NEXT: 360 | S_PROCREF [size = 40] `HelloPoint::HelloPoint`
31CHECK-NEXT: module = 1, sum name = 0, offset = 37635CHECK-NEXT: module = 1, sum name = 0, offset = 376
3236
33CHECK-LABEL: Symbols37CHECK-LABEL: Symbols
deps/lld/test/COFF/pdb-heapsite.yaml+1-1
...@@ -69,7 +69,7 @@ sections:...@@ -69,7 +69,7 @@ sections:
69 RegRelativeSym:69 RegRelativeSym:
70 Offset: 870 Offset: 8
71 Type: 3571 Type: 35
72 Register: CVRegRSP72 Register: RSP
73 VarName: __formal73 VarName: __formal
74 - Kind: S_PROC_ID_END74 - Kind: S_PROC_ID_END
75 ScopeEndSym:75 ScopeEndSym:
deps/lld/test/COFF/pdb-linker-module.test+3-3
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1RUN: echo "/nodefaultlib" > %t.rsp1RUN: echo "/nodefaultlib" > %t.rsp
2RUN: lld-link /debug /pdb:%t.pdb @%t.rsp /entry:main %S/Inputs/pdb-diff.obj2RUN: lld-link /debug /pdb:%t.pdb @%t.rsp /entry:"1 "'"'hello'"'" 2" /manifestuac:"level='asInvoker' uiAccess='false'" %S/Inputs/pdb-diff.obj /force
3RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s3RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s
4RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s4RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s
55
6MODS: Mod 0001 | `* Linker *`6MODS: Mod 0001 | `* Linker *`
7MODS-NEXT: Obj: ``:7MODS-NEXT: Obj: ``:
8MODS-NEXT: debug stream: 12, # files: 0, has ec info: false8MODS-NEXT: debug stream: 13, # files: 0, has ec info: false
9MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 ``9MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 ``
1010
11SYMS: Mod 0001 | `* Linker *`11SYMS: Mod 0001 | `* Linker *`
...@@ -22,4 +22,4 @@ SYMS-NEXT: - {{.*}}lld-link...@@ -22,4 +22,4 @@ SYMS-NEXT: - {{.*}}lld-link
22SYMS-NEXT: - pdb22SYMS-NEXT: - pdb
23SYMS-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb23SYMS-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb
24SYMS-NEXT: - cmd24SYMS-NEXT: - cmd
25SYMS-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj25SYMS-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib "/entry:1 ""hello"" 2" "/manifestuac:level='asInvoker' uiAccess='false'" {{.*}}pdb-diff.obj
deps/lld/test/COFF/pdb-options.test+5
...@@ -6,6 +6,11 @@...@@ -6,6 +6,11 @@
6# RUN: lld-link /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj6# RUN: lld-link /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
7# RUN: not ls %t.pdb7# RUN: not ls %t.pdb
88
9; If /DEBUG:NONE is specified after /DEBUG, /pdb is ignored.
10# RUN: rm -f %t.pdb
11# RUN: lld-link /DEBUG /pdb:%t.pdb /DEBUG:NONE /entry:main /nodefaultlib %t1.obj %t2.obj
12# RUN: not ls %t.pdb
13
9; If /DEBUG and /pdb are specified, it uses the specified name.14; If /DEBUG and /pdb are specified, it uses the specified name.
10# RUN: lld-link /DEBUG /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj15# RUN: lld-link /DEBUG /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
11# RUN: ls %t.pdb16# RUN: ls %t.pdb
deps/lld/test/COFF/pdb-procid-remapping.test+2
...@@ -14,6 +14,7 @@ CHECK-NEXT: type = `0x1004 (int (<no type>))`, debug start = 4, d...@@ -14,6 +14,7 @@ CHECK-NEXT: type = `0x1004 (int (<no type>))`, debug start = 4, d
14CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]14CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]
15CHECK-NEXT: size = 40, padding size = 0, offset to padding = 015CHECK-NEXT: size = 40, padding size = 0, offset to padding = 0
16CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:000016CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000
17CHECK-NEXT: local fp reg = NONE, param fp reg = NONE
17CHECK-NEXT: flags = has async eh | opt speed18CHECK-NEXT: flags = has async eh | opt speed
18CHECK-NEXT: 168 | S_END [size = 4]19CHECK-NEXT: 168 | S_END [size = 4]
19CHECK-LABEL: Mod 0001 |20CHECK-LABEL: Mod 0001 |
...@@ -23,6 +24,7 @@ CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end...@@ -23,6 +24,7 @@ CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end
23CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]24CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]
24CHECK-NEXT: size = 0, padding size = 0, offset to padding = 025CHECK-NEXT: size = 0, padding size = 0, offset to padding = 0
25CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:000026CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000
27CHECK-NEXT: local fp reg = NONE, param fp reg = NONE
26CHECK-NEXT: flags = has async eh | opt speed28CHECK-NEXT: flags = has async eh | opt speed
27CHECK-NEXT: 168 | S_END [size = 4]29CHECK-NEXT: 168 | S_END [size = 4]
28CHECK-LABEL: Mod 0002 |30CHECK-LABEL: Mod 0002 |
deps/lld/test/COFF/pdb-relative-source-lines.test+79-19
...@@ -17,29 +17,89 @@ void bar(void) {...@@ -17,29 +17,89 @@ void bar(void) {
1717
18$ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c18$ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c
1919
20RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t.pdb_lines_1_relative.obj20/pdbsourcepath: only sets the directory that relative paths are considered
21RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t.pdb_lines_2_relative.obj21relative to, so this test needs to pass relative paths to lld-link for:
22RUN: rm -f %t.exe %t.pdb221. The input obj files
23RUN: lld-link -debug -pdbsourcepath:c:\\src -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1_relative.obj %t.pdb_lines_2_relative.obj232. The /pdb: switch
24RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s243. The lld-link invocation itself
2525To achieve this, put all inputs of the lld-link invocation (including lld-link
26CHECK-LABEL: - Module: {{.*}}pdb_lines_1_relative.obj26itself) in a temp directory that's cwd and then make sure to only use relative
27CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1_relative.obj27arguments when calling ./lld-link below.
28RUN: rm -rf %t
29RUN: mkdir %t
30RUN: cp lld-link %t/lld-link
31RUN: cd %t
32
33RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t/pdb_lines_1_relative.obj
34RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t/pdb_lines_2_relative.obj
35RUN: ./lld-link -debug "-pdbsourcepath:c:\src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj
36RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck %s
37RUN: ./lld-link -debug "-pdbsourcepath:/usr/src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj
38RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s
39
40CHECK-LABEL: - Module: 'c:\src\pdb_lines_1_relative.obj'
41CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_1_relative.obj'
28CHECK: SourceFiles:42CHECK: SourceFiles:
29CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'43CHECK-NEXT: - 'c:\src\pdb_lines_1.c'
30CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}foo.h'44CHECK-NEXT: - 'c:\src\foo.h'
31CHECK: Subsections:45CHECK: Subsections:
32CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'46CHECK: - FileName: 'c:\src\pdb_lines_1.c'
33CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h'47CHECK: - FileName: 'c:\src\foo.h'
34CHECK: - !FileChecksums48CHECK: - !FileChecksums
35CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'49CHECK: - FileName: 'c:\src\pdb_lines_1.c'
36CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h'50CHECK: - FileName: 'c:\src\foo.h'
3751
38CHECK-LABEL: - Module: {{.*}}pdb_lines_2_relative.obj52CHECK-LABEL: - Module: 'c:\src\pdb_lines_2_relative.obj'
39CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2_relative.obj53CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_2_relative.obj'
40CHECK: SourceFiles:54CHECK: SourceFiles:
41CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'55CHECK-NEXT: - 'c:\src\pdb_lines_2.c'
42CHECK: Subsections:56CHECK: Subsections:
43CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'57CHECK: - FileName: 'c:\src\pdb_lines_2.c'
44CHECK: - !FileChecksums58CHECK: - !FileChecksums
45CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'59CHECK: - FileName: 'c:\src\pdb_lines_2.c'
60
61CHECK-LABEL: - Kind: S_ENVBLOCK
62CHECK-NEXT: EnvBlockSym:
63CHECK-NEXT: Entries:
64CHECK-NEXT: - cwd
65CHECK-NEXT: - 'c:\src'
66CHECK-NEXT: - exe
67CHECK-NEXT: - 'c:\src\lld-link'
68CHECK-NEXT: - pdb
69CHECK-NEXT: - 'c:\src\out.pdb'
70CHECK-NEXT: - cmd
71CHECK-NEXT: - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
72
73
74POSIX-LABEL: - Module: '/usr/src/pdb_lines_1_relative.obj'
75POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_1_relative.obj'
76POSIX: SourceFiles:
77POSIX-NEXT: - '/usr/src/pdb_lines_1.c'
78POSIX-NEXT: - '/usr/src/foo.h'
79POSIX: Subsections:
80POSIX: - FileName: '/usr/src/pdb_lines_1.c'
81POSIX: - FileName: '/usr/src/foo.h'
82POSIX: - !FileChecksums
83POSIX: - FileName: '/usr/src/pdb_lines_1.c'
84POSIX: - FileName: '/usr/src/foo.h'
85
86POSIX-LABEL: - Module: '/usr/src/pdb_lines_2_relative.obj'
87POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_2_relative.obj'
88POSIX: SourceFiles:
89POSIX-NEXT: - '/usr/src/pdb_lines_2.c'
90POSIX: Subsections:
91POSIX: - FileName: '/usr/src/pdb_lines_2.c'
92POSIX: - !FileChecksums
93POSIX: - FileName: '/usr/src/pdb_lines_2.c'
94
95POSIX-LABEL: - Kind: S_ENVBLOCK
96POSIX-NEXT: EnvBlockSym:
97POSIX-NEXT: Entries:
98POSIX-NEXT: - cwd
99POSIX-NEXT: - '/usr/src'
100POSIX-NEXT: - exe
101POSIX-NEXT: - '/usr/src/lld-link'
102POSIX-NEXT: - pdb
103POSIX-NEXT: - '/usr/src/out.pdb'
104POSIX-NEXT: - cmd
105POSIX-NEXT: - '-debug -pdbsourcepath:/usr/src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
deps/lld/test/COFF/pdb-same-name.test+2-2
...@@ -14,10 +14,10 @@...@@ -14,10 +14,10 @@
14RAW: Modules14RAW: Modules
15RAW-NEXT: ============================================================15RAW-NEXT: ============================================================
16RAW-NEXT: Mod 0000 | `foo.obj`:16RAW-NEXT: Mod 0000 | `foo.obj`:
17RAW-NEXT: Obj: `{{.*}}1\foo.lib`:17RAW-NEXT: Obj: `{{.*}}1{{[\\/]}}foo.lib`:
18RAW-NEXT: debug stream: 11, # files: 1, has ec info: false18RAW-NEXT: debug stream: 11, # files: 1, has ec info: false
19RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``19RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
20RAW-NEXT: Mod 0001 | `foo.obj`:20RAW-NEXT: Mod 0001 | `foo.obj`:
21RAW-NEXT: Obj: `{{.*}}2\foo.lib`:21RAW-NEXT: Obj: `{{.*}}2{{[\\/]}}foo.lib`:
22RAW-NEXT: debug stream: 12, # files: 1, has ec info: false22RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
23RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``23RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
deps/lld/test/COFF/pdb-symbol-types.yaml+6-2
...@@ -17,9 +17,13 @@...@@ -17,9 +17,13 @@
17# CHECK-NEXT: ============================================================17# CHECK-NEXT: ============================================================
18# CHECK-NEXT: Records18# CHECK-NEXT: Records
19# CHECK-NEXT: 48 | S_PROCREF [size = 20] `main`19# CHECK-NEXT: 48 | S_PROCREF [size = 20] `main`
20# CHECK-NEXT: module = 1, sum name = 0, offset = 11620# CHECK-NEXT: module = 1, sum name = 0, offset = 116
21# CHECK-NEXT: 96 | S_UDT [size = 16] `UDT_Foo`
22# CHECK-NEXT: original type = 0x1004
23# CHECK-NEXT: 112 | S_UDT [size = 12] `Foo`
24# CHECK-NEXT: original type = 0x1004
21# CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo`25# CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo`
22# CHECK-NEXT: type = 0x1004 (Foo), addr = 0003:000026# CHECK-NEXT: type = 0x1004 (Foo), addr = 0003:0000
2327
24# CHECK: Symbols28# CHECK: Symbols
25# CHECK: ============================================================29# CHECK: ============================================================
deps/lld/test/COFF/pdb-thunk.yaml+6-6
...@@ -84,7 +84,7 @@ sections:...@@ -84,7 +84,7 @@ sections:
84 RegRelativeSym:84 RegRelativeSym:
85 Offset: 885 Offset: 8
86 Type: 409786 Type: 4097
87 Register: CVRegRSP87 Register: RSP
88 VarName: this88 VarName: this
89 - Kind: S_PROC_ID_END89 - Kind: S_PROC_ID_END
90 ScopeEndSym:90 ScopeEndSym:
...@@ -124,7 +124,7 @@ sections:...@@ -124,7 +124,7 @@ sections:
124 RegRelativeSym:124 RegRelativeSym:
125 Offset: 8125 Offset: 8
126 Type: 4121126 Type: 4121
127 Register: CVRegRSP127 Register: RSP
128 VarName: this128 VarName: this
129 - Kind: S_PROC_ID_END129 - Kind: S_PROC_ID_END
130 ScopeEndSym:130 ScopeEndSym:
...@@ -164,7 +164,7 @@ sections:...@@ -164,7 +164,7 @@ sections:
164 RegRelativeSym:164 RegRelativeSym:
165 Offset: 48165 Offset: 48
166 Type: 4143166 Type: 4143
167 Register: CVRegRSP167 Register: RSP
168 VarName: this168 VarName: this
169 - Kind: S_PROC_ID_END169 - Kind: S_PROC_ID_END
170 ScopeEndSym:170 ScopeEndSym:
...@@ -208,7 +208,7 @@ sections:...@@ -208,7 +208,7 @@ sections:
208 RegRelativeSym:208 RegRelativeSym:
209 Offset: 8209 Offset: 8
210 Type: 4143210 Type: 4143
211 Register: CVRegRSP211 Register: RSP
212 VarName: this212 VarName: this
213 - Kind: S_PROC_ID_END213 - Kind: S_PROC_ID_END
214 ScopeEndSym:214 ScopeEndSym:
...@@ -2176,7 +2176,7 @@ sections:...@@ -2176,7 +2176,7 @@ sections:
2176 RegRelativeSym:2176 RegRelativeSym:
2177 Offset: 82177 Offset: 8
2178 Type: 40972178 Type: 4097
2179 Register: CVRegRSP2179 Register: RSP
2180 VarName: this2180 VarName: this
2181 - Kind: S_PROC_ID_END2181 - Kind: S_PROC_ID_END
2182 ScopeEndSym:2182 ScopeEndSym:
...@@ -2222,7 +2222,7 @@ sections:...@@ -2222,7 +2222,7 @@ sections:
2222 RegRelativeSym:2222 RegRelativeSym:
2223 Offset: 82223 Offset: 8
2224 Type: 41212224 Type: 4121
2225 Register: CVRegRSP2225 Register: RSP
2226 VarName: this2226 VarName: this
2227 - Kind: S_PROC_ID_END2227 - Kind: S_PROC_ID_END
2228 ScopeEndSym:2228 ScopeEndSym:
deps/lld/test/COFF/pdb-type-server-invalid-signature.yaml created+140
...@@ -0,0 +1,140 @@
1
2# RUN: cd %S/Inputs
3# RUN: yaml2obj %s -o %t.obj
4# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
5# RUN: cd %S
6
7# CHECK: warning: Cannot use debug info for {{.*}}.obj
8# CHECK-NEXT: The signature does not match; the file(s) might be out of date
9
10# Also test a valid match
11
12# RUN: cd %S/Inputs
13# RUN: yaml2obj %S/Inputs/pdb-type-server-valid-signature.yaml -o %t2.obj
14# RUN: lld-link %t2.obj -out:%t2.exe -debug -pdb:%t2.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=VALID-SIGNATURE -allow-empty
15# RUN: cd %S
16
17# VALID-SIGNATURE-NOT: warning: Cannot use debug info for {{.*}}.obj
18# VALID-SIGNATURE-NOT: The signature does not match; the file(s) might be out of date
19
20--- !COFF
21header:
22 Machine: IMAGE_FILE_MACHINE_AMD64
23 Characteristics: [ ]
24sections:
25 - Name: '.debug$S'
26 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
27 Alignment: 1
28 Subsections:
29 - !Symbols
30 Records:
31 - Kind: S_GPROC32_ID
32 ProcSym:
33 CodeSize: 3
34 DbgStart: 0
35 DbgEnd: 2
36 FunctionType: 4199
37 Flags: [ ]
38 DisplayName: main
39 - Kind: S_FRAMEPROC
40 FrameProcSym:
41 TotalFrameBytes: 0
42 PaddingFrameBytes: 0
43 OffsetToPadding: 0
44 BytesOfCalleeSavedRegisters: 0
45 OffsetOfExceptionHandler: 0
46 SectionIdOfExceptionHandler: 0
47 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
48 - Kind: S_PROC_ID_END
49 ScopeEndSym:
50 - !Lines
51 CodeSize: 3
52 Flags: [ ]
53 RelocOffset: 0
54 RelocSegment: 0
55 Blocks:
56 - FileName: 'c:\src\llvm-project\build\t.c'
57 Lines:
58 - Offset: 0
59 LineStart: 1
60 IsStatement: true
61 EndDelta: 0
62 Columns:
63 - !FileChecksums
64 Checksums:
65 - FileName: 'c:\src\llvm-project\build\t.c'
66 Kind: MD5
67 Checksum: 270A878DCC1B845655B162F56C4F5020
68 - !StringTable
69 Strings:
70 - 'c:\src\llvm-project\build\t.c'
71 Relocations:
72 - VirtualAddress: 44
73 SymbolName: main
74 Type: IMAGE_REL_AMD64_SECREL
75 - VirtualAddress: 48
76 SymbolName: main
77 Type: IMAGE_REL_AMD64_SECTION
78 - VirtualAddress: 100
79 SymbolName: main
80 Type: IMAGE_REL_AMD64_SECREL
81 - VirtualAddress: 104
82 SymbolName: main
83 Type: IMAGE_REL_AMD64_SECTION
84 - Name: '.debug$T'
85 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
86 Alignment: 1
87 Types:
88 - Kind: LF_TYPESERVER2
89 TypeServer2:
90 Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
91 Age: 18
92 Name: 'pdb-diff-cl.pdb'
93 - Name: '.text$mn'
94 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
95 Alignment: 16
96 SectionData: 33C0C3
97symbols:
98 - Name: '.debug$S'
99 Value: 0
100 SectionNumber: 1
101 SimpleType: IMAGE_SYM_TYPE_NULL
102 ComplexType: IMAGE_SYM_DTYPE_NULL
103 StorageClass: IMAGE_SYM_CLASS_STATIC
104 SectionDefinition:
105 Length: 328
106 NumberOfRelocations: 4
107 NumberOfLinenumbers: 0
108 CheckSum: 0
109 Number: 0
110 - Name: '.debug$T'
111 Value: 0
112 SectionNumber: 2
113 SimpleType: IMAGE_SYM_TYPE_NULL
114 ComplexType: IMAGE_SYM_DTYPE_NULL
115 StorageClass: IMAGE_SYM_CLASS_STATIC
116 SectionDefinition:
117 Length: 564
118 NumberOfRelocations: 0
119 NumberOfLinenumbers: 0
120 CheckSum: 0
121 Number: 0
122 - Name: '.text$mn'
123 Value: 0
124 SectionNumber: 3
125 SimpleType: IMAGE_SYM_TYPE_NULL
126 ComplexType: IMAGE_SYM_DTYPE_NULL
127 StorageClass: IMAGE_SYM_CLASS_STATIC
128 SectionDefinition:
129 Length: 3
130 NumberOfRelocations: 0
131 NumberOfLinenumbers: 0
132 CheckSum: 4021952397
133 Number: 0
134 - Name: main
135 Value: 0
136 SectionNumber: 3
137 SimpleType: IMAGE_SYM_TYPE_NULL
138 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
139 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
140...
deps/lld/test/COFF/pdb-type-server-missing.yaml+18-3
...@@ -1,10 +1,25 @@...@@ -1,10 +1,25 @@
1# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an1# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
2# adjacent type server PDB. Test that LLD fails gracefully on it.2# adjacent type server PDB. Test that LLD fails gracefully on it.
3# Also try linking another OBJ with a reference to the same PDB
34
4# RUN: yaml2obj %s -o %t.obj5# RUN: yaml2obj %s -o %t1.obj
5# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s6# RUN: yaml2obj %p/Inputs/pdb-type-server-missing-2.yaml -o %t2.obj
7# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=WARN
8# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 2>&1 | FileCheck %s -check-prefix=IGNORE -allow-empty
9# RUN: not lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /WX 2>&1 | FileCheck %s -check-prefix=ERR
10# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 /WX 2>&1 | FileCheck %s -check-prefix=IGNORE-ERR -allow-empty
611
7# CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info.12# WARN: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
13# WARN-NEXT: {{N|n}}o such file or directory
14
15# IGNORE-NOT: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
16# IGNORE-NOT: {{N|n}}o such file or directory
17
18# ERR: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
19# ERR-NEXT: {{N|n}}o such file or directory
20
21# IGNORE-ERR-NOT: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
22# IGNORE-ERR-NOT: {{N|n}}o such file or directory
823
9--- !COFF24--- !COFF
10header:25header:
deps/lld/test/COFF/pdb-type-server-native-errors.yaml created+130
...@@ -0,0 +1,130 @@
1
2# RUN: cd %S/Inputs
3# RUN: yaml2obj %s -o %t.obj
4# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
5# RUN: cd %S
6
7# CHECK: warning: Cannot use debug info for {{.*}}.obj
8# CHECK-NEXT: The PDB file is corrupt. MSF superblock is missing
9
10--- !COFF
11header:
12 Machine: IMAGE_FILE_MACHINE_AMD64
13 Characteristics: [ ]
14sections:
15 - Name: '.debug$S'
16 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
17 Alignment: 1
18 Subsections:
19 - !Symbols
20 Records:
21 - Kind: S_GPROC32_ID
22 ProcSym:
23 CodeSize: 3
24 DbgStart: 0
25 DbgEnd: 2
26 FunctionType: 4199
27 Flags: [ ]
28 DisplayName: main
29 - Kind: S_FRAMEPROC
30 FrameProcSym:
31 TotalFrameBytes: 0
32 PaddingFrameBytes: 0
33 OffsetToPadding: 0
34 BytesOfCalleeSavedRegisters: 0
35 OffsetOfExceptionHandler: 0
36 SectionIdOfExceptionHandler: 0
37 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
38 - Kind: S_PROC_ID_END
39 ScopeEndSym:
40 - !Lines
41 CodeSize: 3
42 Flags: [ ]
43 RelocOffset: 0
44 RelocSegment: 0
45 Blocks:
46 - FileName: 'c:\src\llvm-project\build\t.c'
47 Lines:
48 - Offset: 0
49 LineStart: 1
50 IsStatement: true
51 EndDelta: 0
52 Columns:
53 - !FileChecksums
54 Checksums:
55 - FileName: 'c:\src\llvm-project\build\t.c'
56 Kind: MD5
57 Checksum: 270A878DCC1B845655B162F56C4F5020
58 - !StringTable
59 Strings:
60 - 'c:\src\llvm-project\build\t.c'
61 Relocations:
62 - VirtualAddress: 44
63 SymbolName: main
64 Type: IMAGE_REL_AMD64_SECREL
65 - VirtualAddress: 48
66 SymbolName: main
67 Type: IMAGE_REL_AMD64_SECTION
68 - VirtualAddress: 100
69 SymbolName: main
70 Type: IMAGE_REL_AMD64_SECREL
71 - VirtualAddress: 104
72 SymbolName: main
73 Type: IMAGE_REL_AMD64_SECTION
74 - Name: '.debug$T'
75 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
76 Alignment: 1
77 Types:
78 - Kind: LF_TYPESERVER2
79 TypeServer2:
80 Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
81 Age: 18
82 Name: 'bad-block-size.pdb'
83 - Name: '.text$mn'
84 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
85 Alignment: 16
86 SectionData: 33C0C3
87symbols:
88 - Name: '.debug$S'
89 Value: 0
90 SectionNumber: 1
91 SimpleType: IMAGE_SYM_TYPE_NULL
92 ComplexType: IMAGE_SYM_DTYPE_NULL
93 StorageClass: IMAGE_SYM_CLASS_STATIC
94 SectionDefinition:
95 Length: 328
96 NumberOfRelocations: 4
97 NumberOfLinenumbers: 0
98 CheckSum: 0
99 Number: 0
100 - Name: '.debug$T'
101 Value: 0
102 SectionNumber: 2
103 SimpleType: IMAGE_SYM_TYPE_NULL
104 ComplexType: IMAGE_SYM_DTYPE_NULL
105 StorageClass: IMAGE_SYM_CLASS_STATIC
106 SectionDefinition:
107 Length: 564
108 NumberOfRelocations: 0
109 NumberOfLinenumbers: 0
110 CheckSum: 0
111 Number: 0
112 - Name: '.text$mn'
113 Value: 0
114 SectionNumber: 3
115 SimpleType: IMAGE_SYM_TYPE_NULL
116 ComplexType: IMAGE_SYM_DTYPE_NULL
117 StorageClass: IMAGE_SYM_CLASS_STATIC
118 SectionDefinition:
119 Length: 3
120 NumberOfRelocations: 0
121 NumberOfLinenumbers: 0
122 CheckSum: 4021952397
123 Number: 0
124 - Name: main
125 Value: 0
126 SectionNumber: 3
127 SimpleType: IMAGE_SYM_TYPE_NULL
128 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
129 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
130...
deps/lld/test/COFF/pdb-type-server-simple.test+7-5
...@@ -62,10 +62,12 @@ CHECK: {{.*}}: `b.c`...@@ -62,10 +62,12 @@ CHECK: {{.*}}: `b.c`
62CHECK-LABEL: Global Symbols62CHECK-LABEL: Global Symbols
63CHECK: ============================================================63CHECK: ============================================================
64CHECK-NEXT: Records64CHECK-NEXT: Records
65CHECK-NEXT: 36 | S_PROCREF [size = 20] `main`65CHECK-NEXT: 36 | S_PROCREF [size = 20] `main`
66CHECK-NEXT: module = 1, sum name = 0, offset = 10466CHECK-NEXT: module = 1, sum name = 0, offset = 104
67CHECK-NEXT: 56 | S_PROCREF [size = 16] `g`67CHECK-NEXT: 68 | S_PROCREF [size = 16] `g`
68CHECK-NEXT: module = 2, sum name = 0, offset = 10468CHECK-NEXT: module = 2, sum name = 0, offset = 104
69CHECK-NEXT: 56 | S_UDT [size = 12] `Foo`
70CHECK-NEXT: original type = 0x1006
6971
70CHECK-LABEL: Symbols72CHECK-LABEL: Symbols
71CHECK: ============================================================73CHECK: ============================================================
...@@ -89,7 +91,7 @@ CHECK: size = 0, padding size = 0, offset to padding = 0...@@ -89,7 +91,7 @@ CHECK: size = 0, padding size = 0, offset to padding = 0
89CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:000091CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
90CHECK: flags = has async eh | opt speed92CHECK: flags = has async eh | opt speed
91CHECK: 180 | S_REGREL32 [size = 16] `p`93CHECK: 180 | S_REGREL32 [size = 16] `p`
92CHECK: type = [[FOO_PTR]] (Foo*), register = CVRegRSP, offset = 894CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8
93CHECK: 196 | S_END [size = 4]95CHECK: 196 | S_END [size = 4]
94CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`96CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
95CHECK-LABEL: Mod 0002 | `* Linker *`:97CHECK-LABEL: Mod 0002 | `* Linker *`:
deps/lld/test/COFF/pdb.test-19
...@@ -193,25 +193,6 @@ RAW-NEXT: flags = function, addr = 0001:0000...@@ -193,25 +193,6 @@ RAW-NEXT: flags = function, addr = 0001:0000
193RAW-NEXT: 0 | S_PUB32 [size = 20] `foo`193RAW-NEXT: 0 | S_PUB32 [size = 20] `foo`
194RAW-NEXT: flags = function, addr = 0001:0016194RAW-NEXT: flags = function, addr = 0001:0016
195RAW-NOT: S_PUB32195RAW-NOT: S_PUB32
196RAW-NEXT: Hash Bitmap (
197RAW-NEXT: 0000: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
198RAW-NEXT: 0020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
199RAW-NEXT: 0040: 00000000 20000000 00000000 00000000 00000000 00000000 00000000 00000000 |.... ...........................|
200RAW-NEXT: 0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
201RAW-NEXT: 0080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
202RAW-NEXT: 00A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
203RAW-NEXT: 00C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
204RAW-NEXT: 00E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
205RAW-NEXT: 0100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
206RAW-NEXT: 0120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
207RAW-NEXT: 0140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
208RAW-NEXT: 0160: 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
209RAW-NEXT: 0180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
210RAW-NEXT: 01A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
211RAW-NEXT: 01C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
212RAW-NEXT: 01E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................|
213RAW-NEXT: 0200: 00000000 |....|
214RAW-NEXT: )
215RAW-NEXT: Hash Entries196RAW-NEXT: Hash Entries
216RAW-NEXT: off = 21, refcnt = 1197RAW-NEXT: off = 21, refcnt = 1
217RAW-NEXT: off = 1, refcnt = 1198RAW-NEXT: off = 1, refcnt = 1
deps/lld/test/COFF/pdbaltpath.test created+39
...@@ -0,0 +1,39 @@
1# RUN: yaml2obj %p/Inputs/empty.yaml > %t.obj
2
3# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:hello.pdb
4# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix HELLO %s
5# HELLO: PDBFileName: hello.pdb
6
7# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_Pdb%
8# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix PDBVAR %s
9# PDBVAR: PDBFileName: pdbaltpath.test.tmp.pdb
10
11# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_ExT%.pdb
12# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix EXTVAR %s
13# EXTVAR: PDBFileName: fooexe.pdb
14
15# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_PDB
16# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE %s
17# NOCLOSE: PDBFileName: %_PDB
18
19# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB
20# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE2 %s
21# NOCLOSE2: PDBFileName: foo%_PDB
22
23# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT
24# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSEONE %s
25# CLOSEONE: PDBFileName: foopdbaltpath.test.tmp.pdbbar%_EXT
26
27# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%
28# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO %s
29# CLOSETWO: PDBFileName: foopdbaltpath.test.tmp.pdbbarexe
30
31# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%a
32# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO2 %s
33# CLOSETWO2: PDBFileName: foopdbaltpath.test.tmp.pdbbarexea
34
35# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%FoO%bar%r%a 2>&1 | FileCheck --check-prefix UNKNOWN-WARN %s
36# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix ENVVARS %s
37# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %FoO% as literal
38# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %r% as literal
39# ENVVARS: PDBFileName: foo%FoO%bar%r%a
deps/lld/test/COFF/precomp-link.test created+42
...@@ -0,0 +1,42 @@
1RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
2RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
3
4RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
5RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
6
7RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
8
9RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
10
11FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj' [LNK4099]
12FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
13
14FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj' [LNK4099]
15FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference '{{.*}}precomp.obj': The path to this file must be provided on the command-line
16
17CHECK: Types (TPI Stream)
18CHECK-NOT: LF_PRECOMP
19CHECK-NOT: LF_ENDPRECOMP
20
21// precomp.h
22#pragma once
23int Function(char A);
24
25// precomp.cpp
26#include "precomp.h"
27
28// a.cpp
29#include "precomp.h"
30int main(void) {
31 Function('a');
32 return 0;
33}
34
35// b.cpp
36#include "precomp.h"
37int Function(char a) {
38 return (int)a;
39}
40
41// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c
42// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c
deps/lld/test/COFF/reloc-discarded.s+1
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:noref 2>&1 | FileCheck %s10# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:noref 2>&1 | FileCheck %s
1111
12# CHECK: error: relocation against symbol in discarded section: assoc_global12# CHECK: error: relocation against symbol in discarded section: assoc_global
13# CHECK: >>> referenced by {{.*}}reloc-discarded{{.*}}.obj:(main)
1314
14 .section .bss,"bw",discard,main_global15 .section .bss,"bw",discard,main_global
15 .globl main_global16 .globl main_global
deps/lld/test/COFF/rsds.test+120-6
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1# RUN: yaml2obj %s > %t.obj1# RUN: yaml2obj %s > %t.obj
22
3# RUN: rm -f %t.dll %t.pdb3# RUN: rm -f %t.dll %t.pdb
4# RUN: lld-link /debug /pdbaltpath:test1.pdb /dll /out:%t.dll /entry:DllMain %t.obj4# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
5# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt5# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt
6# RUN: lld-link /debug /pdbaltpath:test2.pdb /dll /out:%t.dll /entry:DllMain %t.obj6# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
7# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt7# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt
8# RUN: cat %t.1.txt %t.2.txt | FileCheck %s8# RUN: cat %t.1.txt %t.2.txt | FileCheck %s
99
...@@ -12,7 +12,19 @@...@@ -12,7 +12,19 @@
12# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt12# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
13# RUN: lld-link /debug /pdb:%t2.pdb /dll /out:%t.dll /entry:DllMain %t.obj13# RUN: lld-link /debug /pdb:%t2.pdb /dll /out:%t.dll /entry:DllMain %t.obj
14# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt14# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
15# RUN: cat %t.3.txt %t.4.txt | FileCheck %s15# RUN: cat %t.3.txt %t.4.txt | FileCheck --check-prefix TWOPDBS %s
16
17# RUN: rm -f %t.dll %t.pdb
18# RUN: lld-link /Brepro /dll /out:%t.dll /entry:DllMain %t.obj
19# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRO %s
20
21# RUN: rm -f %t.dll %t.pdb
22# RUN: lld-link /Brepro /debug /dll /out:%t.dll /entry:DllMain %t.obj
23# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRODEBUG %s
24
25# RUN: rm -f %t.dll %t.pdb
26# RUN: lld-link /lldmingw /debug:dwarf /dll /out:%t.dll /entry:DllMain %t.obj
27# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix MINGW %s
1628
17# CHECK: File: [[FILE:.*]].dll29# CHECK: File: [[FILE:.*]].dll
18# CHECK: DebugDirectory [30# CHECK: DebugDirectory [
...@@ -29,7 +41,7 @@...@@ -29,7 +41,7 @@
29# CHECK: PDBSignature: 0x5344535241# CHECK: PDBSignature: 0x53445352
30# CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]42# CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
31# CHECK: PDBAge: 143# CHECK: PDBAge: 1
32# CHECK: PDBFileName: {{.*}}1.pdb44# CHECK: PDBFileName: {{.*}}.pdb
33# CHECK: }45# CHECK: }
34# CHECK: }46# CHECK: }
35# CHECK: ]47# CHECK: ]
...@@ -47,12 +59,114 @@...@@ -47,12 +59,114 @@
47# CHECK: PDBInfo {59# CHECK: PDBInfo {
48# CHECK: PDBSignature: 0x5344535260# CHECK: PDBSignature: 0x53445352
49# CHECK: PDBGUID: [[GUID]]61# CHECK: PDBGUID: [[GUID]]
50# CHECK: PDBAge: 262# CHECK: PDBAge: 1
51# CHECK: PDBFileName: {{.*}}2.pdb63# CHECK: PDBFileName: {{.*}}.pdb
52# CHECK: }64# CHECK: }
53# CHECK: }65# CHECK: }
54# CHECK: ]66# CHECK: ]
5567
68# TWOPDBS: File: [[FILE:.*]].dll
69# TWOPDBS: DebugDirectory [
70# TWOPDBS: DebugEntry {
71# TWOPDBS: Characteristics: 0x0
72# TWOPDBS: TimeDateStamp:
73# TWOPDBS: MajorVersion: 0x0
74# TWOPDBS: MinorVersion: 0x0
75# TWOPDBS: Type: CodeView (0x2)
76# TWOPDBS: SizeOfData: 0x{{[^0]}}
77# TWOPDBS: AddressOfRawData: 0x{{[^0]}}
78# TWOPDBS: PointerToRawData: 0x{{[^0]}}
79# TWOPDBS: PDBInfo {
80# TWOPDBS: PDBSignature: 0x53445352
81# TWOPDBS: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
82# TWOPDBS: PDBAge: 1
83# TWOPDBS: PDBFileName: {{.*}}.pdb
84# TWOPDBS: }
85# TWOPDBS: }
86# TWOPDBS: ]
87# TWOPDBS: File: [[FILE]].dll
88# TWOPDBS: DebugDirectory [
89# TWOPDBS: DebugEntry {
90# TWOPDBS: Characteristics: 0x0
91# TWOPDBS: TimeDateStamp:
92# TWOPDBS: MajorVersion: 0x0
93# TWOPDBS: MinorVersion: 0x0
94# TWOPDBS: Type: CodeView (0x2)
95# TWOPDBS: SizeOfData: 0x{{[^0]}}
96# TWOPDBS: AddressOfRawData: 0x{{[^0]}}
97# TWOPDBS: PointerToRawData: 0x{{[^0]}}
98# TWOPDBS: PDBInfo {
99# TWOPDBS: PDBSignature: 0x53445352
100# TWOPDBS-NOT: PDBGUID: [[GUID]]
101# TWOPDBS: PDBAge: 1
102# TWOPDBS: PDBFileName: {{.*}}.pdb
103# TWOPDBS: }
104# TWOPDBS: }
105# TWOPDBS: ]
106
107# REPRO: File: {{.*}}.dll
108# REPRO: DebugDirectory [
109# REPRO: DebugEntry {
110# REPRO: Characteristics: 0x0
111# REPRO: TimeDateStamp:
112# REPRO: MajorVersion: 0x0
113# REPRO: MinorVersion: 0x0
114# REPRO: Type: Repro (0x10)
115# REPRO: SizeOfData: 0x0
116# REPRO: AddressOfRawData: 0x0
117# REPRO: PointerToRawData: 0x0
118# REPRO: }
119# REPRO: ]
120
121# REPRODEBUG: File: {{.*}}.dll
122# REPRODEBUG: DebugDirectory [
123# REPRODEBUG: DebugEntry {
124# REPRODEBUG: Characteristics: 0x0
125# REPRODEBUG: TimeDateStamp:
126# REPRODEBUG: MajorVersion: 0x0
127# REPRODEBUG: MinorVersion: 0x0
128# REPRODEBUG: Type: CodeView (0x2)
129# REPRODEBUG: SizeOfData: 0x{{[^0]}}
130# REPRODEBUG: AddressOfRawData: 0x{{[^0]}}
131# REPRODEBUG: PointerToRawData: 0x{{[^0]}}
132# REPRODEBUG: PDBInfo {
133# REPRODEBUG: PDBSignature: 0x53445352
134# REPRODEBUG: PDBGUID:
135# REPRODEBUG: PDBAge: 1
136# REPRODEBUG: PDBFileName:
137# REPRODEBUG: }
138# REPRODEBUG: }
139# REPRODEBUG: DebugEntry {
140# REPRODEBUG: Characteristics: 0x0
141# REPRODEBUG: TimeDateStamp:
142# REPRODEBUG: MajorVersion: 0x0
143# REPRODEBUG: MinorVersion: 0x0
144# REPRODEBUG: Type: Repro (0x10)
145# REPRODEBUG: SizeOfData: 0x0
146# REPRODEBUG: AddressOfRawData: 0x0
147# REPRODEBUG: PointerToRawData: 0x0
148# REPRODEBUG: }
149# REPRODEBUG: ]
150
151# MINGW: File: {{.*}}.dll
152# MINGW: DebugDirectory [
153# MINGW: DebugEntry {
154# MINGW: Characteristics: 0x0
155# MINGW: TimeDateStamp:
156# MINGW: MajorVersion: 0x0
157# MINGW: MinorVersion: 0x0
158# MINGW: Type: CodeView (0x2)
159# MINGW: SizeOfData: 0x{{[^0]}}
160# MINGW: AddressOfRawData: 0x{{[^0]}}
161# MINGW: PointerToRawData: 0x{{[^0]}}
162# MINGW: PDBInfo {
163# MINGW: PDBSignature: 0x53445352
164# MINGW: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
165# MINGW: PDBAge: 1
166# MINGW: PDBFileName:
167# MINGW: }
168# MINGW: }
169# MINGW: ]
56--- !COFF170--- !COFF
57header:171header:
58 Machine: IMAGE_FILE_MACHINE_I386172 Machine: IMAGE_FILE_MACHINE_I386
deps/lld/test/COFF/s_udt.s created+476
...@@ -0,0 +1,476 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc < %s > %t.obj
3# RUN: lld-link /DEBUG:FULL /nodefaultlib /entry:main %t.obj /PDB:%t.pdb /OUT:%t.exe
4# RUN: llvm-pdbutil dump -types -globals -symbols -modi=0 %t.pdb | FileCheck %s
5
6# CHECK: Types (TPI Stream)
7# CHECK-NEXT: ============================================================
8# CHECK: 0x1003 | LF_STRUCTURE [size = 44] `Struct`
9# CHECK-NEXT: unique name: `.?AUStruct@@`
10# CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: <no type>
11# CHECK-NEXT: options: forward ref (-> 0x1006) | has unique name, sizeof 0
12# CHECK-NEXT: 0x1004 | LF_POINTER [size = 12]
13# CHECK-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr64
14# CHECK: 0x1006 | LF_STRUCTURE [size = 44] `Struct`
15# CHECK-NEXT: unique name: `.?AUStruct@@`
16# CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x1005
17# CHECK-NEXT: options: has unique name, sizeof 4
18# CHECK: Global Symbols
19# CHECK-NEXT: ============================================================
20# CHECK: {{.*}} | S_UDT [size = 24] `StructTypedef`
21# CHECK: original type = 0x1003
22# CHECK: {{.*}} | S_UDT [size = 16] `Struct`
23# CHECK: original type = 0x1006
24# CHECK: {{.*}} | S_UDT [size = 20] `IntTypedef`
25# CHECK: original type = 0x0074 (int)
26# CHECK: Symbols
27# CHECK-NEXT: ============================================================
28# CHECK: {{.*}} | S_GPROC32 [size = 44] `main`
29# CHECK-NEXT: parent = 0, end = 252, addr = 0001:0000, code size = 52
30# CHECK-NEXT: type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none
31# CHECK-NOT: {{.*}} | S_END
32# CHECK: {{.*}} | S_UDT [size = 28] `main::LocalTypedef`
33# CHECK-NEXT: original type = 0x1004
34# CHECK: {{.*}} | S_END [size = 4]
35
36# source code to re-generate:
37# clang-cl /Z7 /GS- /GR- /c foo.cpp
38#
39# struct Struct {
40# int x;
41# };
42#
43# using IntTypedef = int;
44# using StructTypedef = Struct;
45# Struct S;
46# StructTypedef SS;
47# IntTypedef I;
48#
49# int main(int argc, char **argv) {
50# using LocalTypedef = Struct*;
51# LocalTypedef SPtr;
52# return I + S.x + SS.x + SPtr->x;
53# }
54
55 .text
56 .def @feat.00;
57 .scl 3;
58 .type 0;
59 .endef
60 .globl @feat.00
61.set @feat.00, 0
62 .intel_syntax noprefix
63 .def main;
64 .scl 2;
65 .type 32;
66 .endef
67 .globl main # -- Begin function main
68 .p2align 4, 0x90
69main: # @main
70.Lfunc_begin0:
71 .cv_func_id 0
72 .cv_file 1 "D:\\src\\llvmbuild\\cl\\Debug\\x64\\foo.cpp" "2B62298EE3EEF94E1D81FDFE18BD46A6" 1
73 .cv_loc 0 1 12 0 # foo.cpp:12:0
74.seh_proc main
75# %bb.0: # %entry
76 sub rsp, 32
77 .seh_stackalloc 32
78 .seh_endprologue
79 mov dword ptr [rsp + 28], 0
80 mov qword ptr [rsp + 16], rdx
81 mov dword ptr [rsp + 12], ecx
82.Ltmp0:
83 .cv_loc 0 1 15 0 # foo.cpp:15:0
84 mov ecx, dword ptr [rip + "?I@@3HA"]
85 add ecx, dword ptr [rip + "?S@@3UStruct@@A"]
86 add ecx, dword ptr [rip + "?SS@@3UStruct@@A"]
87 mov rdx, qword ptr [rsp]
88 add ecx, dword ptr [rdx]
89 mov eax, ecx
90 add rsp, 32
91 ret
92.Ltmp1:
93.Lfunc_end0:
94 .seh_handlerdata
95 .text
96 .seh_endproc
97 # -- End function
98 .bss
99 .globl "?S@@3UStruct@@A" # @"?S@@3UStruct@@A"
100 .p2align 2
101"?S@@3UStruct@@A":
102 .zero 4
103
104 .globl "?SS@@3UStruct@@A" # @"?SS@@3UStruct@@A"
105 .p2align 2
106"?SS@@3UStruct@@A":
107 .zero 4
108
109 .globl "?I@@3HA" # @"?I@@3HA"
110 .p2align 2
111"?I@@3HA":
112 .long 0 # 0x0
113
114 .section .drectve,"yn"
115 .ascii " /DEFAULTLIB:libcmt.lib"
116 .ascii " /DEFAULTLIB:oldnames.lib"
117 .section .debug$S,"dr"
118 .p2align 2
119 .long 4 # Debug section magic
120 .long 241
121 .long .Ltmp3-.Ltmp2 # Subsection size
122.Ltmp2:
123 .short .Ltmp5-.Ltmp4 # Record length
124.Ltmp4:
125 .short 4412 # Record kind: S_COMPILE3
126 .long 1 # Flags and language
127 .short 208 # CPUType
128 .short 8 # Frontend version
129 .short 0
130 .short 0
131 .short 0
132 .short 8000 # Backend version
133 .short 0
134 .short 0
135 .short 0
136 .asciz "clang version 8.0.0 " # Null-terminated compiler version string
137.Ltmp5:
138.Ltmp3:
139 .p2align 2
140 .long 241 # Symbol subsection for main
141 .long .Ltmp7-.Ltmp6 # Subsection size
142.Ltmp6:
143 .short .Ltmp9-.Ltmp8 # Record length
144.Ltmp8:
145 .short 4423 # Record kind: S_GPROC32_ID
146 .long 0 # PtrParent
147 .long 0 # PtrEnd
148 .long 0 # PtrNext
149 .long .Lfunc_end0-main # Code size
150 .long 0 # Offset after prologue
151 .long 0 # Offset before epilogue
152 .long 4099 # Function type index
153 .secrel32 main # Function section relative address
154 .secidx main # Function section index
155 .byte 0 # Flags
156 .asciz "main" # Function name
157.Ltmp9:
158 .short .Ltmp11-.Ltmp10 # Record length
159.Ltmp10:
160 .short 4114 # Record kind: S_FRAMEPROC
161 .long 32 # FrameSize
162 .long 0 # Padding
163 .long 0 # Offset of padding
164 .long 0 # Bytes of callee saved registers
165 .long 0 # Exception handler offset
166 .short 0 # Exception handler section
167 .long 81920 # Flags (defines frame register)
168.Ltmp11:
169 .short .Ltmp13-.Ltmp12 # Record length
170.Ltmp12:
171 .short 4414 # Record kind: S_LOCAL
172 .long 116 # TypeIndex
173 .short 1 # Flags
174 .asciz "argc"
175.Ltmp13:
176 .cv_def_range .Ltmp0 .Ltmp1, "B\021\f\000\000\000"
177 .short .Ltmp15-.Ltmp14 # Record length
178.Ltmp14:
179 .short 4414 # Record kind: S_LOCAL
180 .long 4096 # TypeIndex
181 .short 1 # Flags
182 .asciz "argv"
183.Ltmp15:
184 .cv_def_range .Ltmp0 .Ltmp1, "B\021\020\000\000\000"
185 .short .Ltmp17-.Ltmp16 # Record length
186.Ltmp16:
187 .short 4414 # Record kind: S_LOCAL
188 .long 4101 # TypeIndex
189 .short 0 # Flags
190 .asciz "SPtr"
191.Ltmp17:
192 .cv_def_range .Ltmp0 .Ltmp1, "B\021\000\000\000\000"
193 .short .Ltmp19-.Ltmp18 # Record length
194.Ltmp18:
195 .short 4360 # Record kind: S_UDT
196 .long 4101 # Type
197 .asciz "main::LocalTypedef"
198.Ltmp19:
199 .short 2 # Record length
200 .short 4431 # Record kind: S_PROC_ID_END
201.Ltmp7:
202 .p2align 2
203 .cv_linetable 0, main, .Lfunc_end0
204 .long 241 # Symbol subsection for globals
205 .long .Ltmp21-.Ltmp20 # Subsection size
206.Ltmp20:
207 .short .Ltmp23-.Ltmp22 # Record length
208.Ltmp22:
209 .short 4365 # Record kind: S_GDATA32
210 .long 4103 # Type
211 .secrel32 "?S@@3UStruct@@A" # DataOffset
212 .secidx "?S@@3UStruct@@A" # Segment
213 .asciz "S" # Name
214.Ltmp23:
215 .short .Ltmp25-.Ltmp24 # Record length
216.Ltmp24:
217 .short 4365 # Record kind: S_GDATA32
218 .long 4100 # Type
219 .secrel32 "?SS@@3UStruct@@A" # DataOffset
220 .secidx "?SS@@3UStruct@@A" # Segment
221 .asciz "SS" # Name
222.Ltmp25:
223 .short .Ltmp27-.Ltmp26 # Record length
224.Ltmp26:
225 .short 4365 # Record kind: S_GDATA32
226 .long 116 # Type
227 .secrel32 "?I@@3HA" # DataOffset
228 .secidx "?I@@3HA" # Segment
229 .asciz "I" # Name
230.Ltmp27:
231.Ltmp21:
232 .p2align 2
233 .long 241
234 .long .Ltmp29-.Ltmp28 # Subsection size
235.Ltmp28:
236 .short .Ltmp31-.Ltmp30 # Record length
237.Ltmp30:
238 .short 4360 # Record kind: S_UDT
239 .long 4103 # Type
240 .asciz "Struct"
241.Ltmp31:
242 .short .Ltmp33-.Ltmp32 # Record length
243.Ltmp32:
244 .short 4360 # Record kind: S_UDT
245 .long 4100 # Type
246 .asciz "StructTypedef"
247.Ltmp33:
248 .short .Ltmp35-.Ltmp34 # Record length
249.Ltmp34:
250 .short 4360 # Record kind: S_UDT
251 .long 116 # Type
252 .asciz "IntTypedef"
253.Ltmp35:
254.Ltmp29:
255 .p2align 2
256 .cv_filechecksums # File index to string table offset subsection
257 .cv_stringtable # String table
258 .long 241
259 .long .Ltmp37-.Ltmp36 # Subsection size
260.Ltmp36:
261 .short 6 # Record length
262 .short 4428 # Record kind: S_BUILDINFO
263 .long 4108 # LF_BUILDINFO index
264.Ltmp37:
265 .p2align 2
266 .section .debug$T,"dr"
267 .p2align 2
268 .long 4 # Debug section magic
269 # Pointer (0x1000) {
270 # TypeLeafKind: LF_POINTER (0x1002)
271 # PointeeType: char* (0x670)
272 # PtrType: Near64 (0xC)
273 # PtrMode: Pointer (0x0)
274 # IsFlat: 0
275 # IsConst: 0
276 # IsVolatile: 0
277 # IsUnaligned: 0
278 # IsRestrict: 0
279 # IsThisPtr&: 0
280 # IsThisPtr&&: 0
281 # SizeOf: 8
282 # }
283 .byte 0x0a, 0x00, 0x02, 0x10
284 .byte 0x70, 0x06, 0x00, 0x00
285 .byte 0x0c, 0x00, 0x01, 0x00
286 # ArgList (0x1001) {
287 # TypeLeafKind: LF_ARGLIST (0x1201)
288 # NumArgs: 2
289 # Arguments [
290 # ArgType: int (0x74)
291 # ArgType: char** (0x1000)
292 # ]
293 # }
294 .byte 0x0e, 0x00, 0x01, 0x12
295 .byte 0x02, 0x00, 0x00, 0x00
296 .byte 0x74, 0x00, 0x00, 0x00
297 .byte 0x00, 0x10, 0x00, 0x00
298 # Procedure (0x1002) {
299 # TypeLeafKind: LF_PROCEDURE (0x1008)
300 # ReturnType: int (0x74)
301 # CallingConvention: NearC (0x0)
302 # FunctionOptions [ (0x0)
303 # ]
304 # NumParameters: 2
305 # ArgListType: (int, char**) (0x1001)
306 # }
307 .byte 0x0e, 0x00, 0x08, 0x10
308 .byte 0x74, 0x00, 0x00, 0x00
309 .byte 0x00, 0x00, 0x02, 0x00
310 .byte 0x01, 0x10, 0x00, 0x00
311 # FuncId (0x1003) {
312 # TypeLeafKind: LF_FUNC_ID (0x1601)
313 # ParentScope: 0x0
314 # FunctionType: int (int, char**) (0x1002)
315 # Name: main
316 # }
317 .byte 0x12, 0x00, 0x01, 0x16
318 .byte 0x00, 0x00, 0x00, 0x00
319 .byte 0x02, 0x10, 0x00, 0x00
320 .byte 0x6d, 0x61, 0x69, 0x6e
321 .byte 0x00, 0xf3, 0xf2, 0xf1
322 # Struct (0x1004) {
323 # TypeLeafKind: LF_STRUCTURE (0x1505)
324 # MemberCount: 0
325 # Properties [ (0x280)
326 # ForwardReference (0x80)
327 # HasUniqueName (0x200)
328 # ]
329 # FieldList: 0x0
330 # DerivedFrom: 0x0
331 # VShape: 0x0
332 # SizeOf: 0
333 # Name: Struct
334 # LinkageName: .?AUStruct@@
335 # }
336 .byte 0x2a, 0x00, 0x05, 0x15
337 .byte 0x00, 0x00, 0x80, 0x02
338 .byte 0x00, 0x00, 0x00, 0x00
339 .byte 0x00, 0x00, 0x00, 0x00
340 .byte 0x00, 0x00, 0x00, 0x00
341 .byte 0x00, 0x00, 0x53, 0x74
342 .byte 0x72, 0x75, 0x63, 0x74
343 .byte 0x00, 0x2e, 0x3f, 0x41
344 .byte 0x55, 0x53, 0x74, 0x72
345 .byte 0x75, 0x63, 0x74, 0x40
346 .byte 0x40, 0x00, 0xf2, 0xf1
347 # Pointer (0x1005) {
348 # TypeLeafKind: LF_POINTER (0x1002)
349 # PointeeType: Struct (0x1004)
350 # PtrType: Near64 (0xC)
351 # PtrMode: Pointer (0x0)
352 # IsFlat: 0
353 # IsConst: 0
354 # IsVolatile: 0
355 # IsUnaligned: 0
356 # IsRestrict: 0
357 # IsThisPtr&: 0
358 # IsThisPtr&&: 0
359 # SizeOf: 8
360 # }
361 .byte 0x0a, 0x00, 0x02, 0x10
362 .byte 0x04, 0x10, 0x00, 0x00
363 .byte 0x0c, 0x00, 0x01, 0x00
364 # FieldList (0x1006) {
365 # TypeLeafKind: LF_FIELDLIST (0x1203)
366 # DataMember {
367 # TypeLeafKind: LF_MEMBER (0x150D)
368 # AccessSpecifier: Public (0x3)
369 # Type: int (0x74)
370 # FieldOffset: 0x0
371 # Name: x
372 # }
373 # }
374 .byte 0x0e, 0x00, 0x03, 0x12
375 .byte 0x0d, 0x15, 0x03, 0x00
376 .byte 0x74, 0x00, 0x00, 0x00
377 .byte 0x00, 0x00, 0x78, 0x00
378 # Struct (0x1007) {
379 # TypeLeafKind: LF_STRUCTURE (0x1505)
380 # MemberCount: 1
381 # Properties [ (0x200)
382 # HasUniqueName (0x200)
383 # ]
384 # FieldList: <field list> (0x1006)
385 # DerivedFrom: 0x0
386 # VShape: 0x0
387 # SizeOf: 4
388 # Name: Struct
389 # LinkageName: .?AUStruct@@
390 # }
391 .byte 0x2a, 0x00, 0x05, 0x15
392 .byte 0x01, 0x00, 0x00, 0x02
393 .byte 0x06, 0x10, 0x00, 0x00
394 .byte 0x00, 0x00, 0x00, 0x00
395 .byte 0x00, 0x00, 0x00, 0x00
396 .byte 0x04, 0x00, 0x53, 0x74
397 .byte 0x72, 0x75, 0x63, 0x74
398 .byte 0x00, 0x2e, 0x3f, 0x41
399 .byte 0x55, 0x53, 0x74, 0x72
400 .byte 0x75, 0x63, 0x74, 0x40
401 .byte 0x40, 0x00, 0xf2, 0xf1
402 # StringId (0x1008) {
403 # TypeLeafKind: LF_STRING_ID (0x1605)
404 # Id: 0x0
405 # StringData: D:\src\llvmbuild\cl\Debug\x64\foo.cpp
406 # }
407 .byte 0x2e, 0x00, 0x05, 0x16
408 .byte 0x00, 0x00, 0x00, 0x00
409 .byte 0x44, 0x3a, 0x5c, 0x73
410 .byte 0x72, 0x63, 0x5c, 0x6c
411 .byte 0x6c, 0x76, 0x6d, 0x62
412 .byte 0x75, 0x69, 0x6c, 0x64
413 .byte 0x5c, 0x63, 0x6c, 0x5c
414 .byte 0x44, 0x65, 0x62, 0x75
415 .byte 0x67, 0x5c, 0x78, 0x36
416 .byte 0x34, 0x5c, 0x66, 0x6f
417 .byte 0x6f, 0x2e, 0x63, 0x70
418 .byte 0x70, 0x00, 0xf2, 0xf1
419 # UdtSourceLine (0x1009) {
420 # TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
421 # UDT: Struct (0x1007)
422 # SourceFile: D:\src\llvmbuild\cl\Debug\x64\foo.cpp (0x1008)
423 # LineNumber: 1
424 # }
425 .byte 0x0e, 0x00, 0x06, 0x16
426 .byte 0x07, 0x10, 0x00, 0x00
427 .byte 0x08, 0x10, 0x00, 0x00
428 .byte 0x01, 0x00, 0x00, 0x00
429 # StringId (0x100A) {
430 # TypeLeafKind: LF_STRING_ID (0x1605)
431 # Id: 0x0
432 # StringData: D:\\src\\llvmbuild\\cl\\Debug\\x64
433 # }
434 .byte 0x2a, 0x00, 0x05, 0x16
435 .byte 0x00, 0x00, 0x00, 0x00
436 .byte 0x44, 0x3a, 0x5c, 0x5c
437 .byte 0x73, 0x72, 0x63, 0x5c
438 .byte 0x5c, 0x6c, 0x6c, 0x76
439 .byte 0x6d, 0x62, 0x75, 0x69
440 .byte 0x6c, 0x64, 0x5c, 0x5c
441 .byte 0x63, 0x6c, 0x5c, 0x5c
442 .byte 0x44, 0x65, 0x62, 0x75
443 .byte 0x67, 0x5c, 0x5c, 0x78
444 .byte 0x36, 0x34, 0x00, 0xf1
445 # StringId (0x100B) {
446 # TypeLeafKind: LF_STRING_ID (0x1605)
447 # Id: 0x0
448 # StringData: foo.cpp
449 # }
450 .byte 0x0e, 0x00, 0x05, 0x16
451 .byte 0x00, 0x00, 0x00, 0x00
452 .byte 0x66, 0x6f, 0x6f, 0x2e
453 .byte 0x63, 0x70, 0x70, 0x00
454 # BuildInfo (0x100C) {
455 # TypeLeafKind: LF_BUILDINFO (0x1603)
456 # NumArgs: 5
457 # Arguments [
458 # ArgType: D:\\src\\llvmbuild\\cl\\Debug\\x64 (0x100A)
459 # ArgType: 0x0
460 # ArgType: foo.cpp (0x100B)
461 # ArgType: 0x0
462 # ArgType: 0x0
463 # ]
464 # }
465 .byte 0x1a, 0x00, 0x03, 0x16
466 .byte 0x05, 0x00, 0x0a, 0x10
467 .byte 0x00, 0x00, 0x00, 0x00
468 .byte 0x00, 0x00, 0x0b, 0x10
469 .byte 0x00, 0x00, 0x00, 0x00
470 .byte 0x00, 0x00, 0x00, 0x00
471 .byte 0x00, 0x00, 0xf2, 0xf1
472
473 .addrsig
474 .addrsig_sym "?S@@3UStruct@@A"
475 .addrsig_sym "?SS@@3UStruct@@A"
476 .addrsig_sym "?I@@3HA"
deps/lld/test/COFF/subsystem-inference-mingw.s created+17
...@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.o
3
4# RUN: lld-link -lldmingw %t.o -out:%t.exe
5# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
6
7# CHECK: AddressOfEntryPoint: 0x1001
8# CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
9
10 .text
11 .globl foo
12 .globl mainCRTStartup
13foo:
14 ret
15mainCRTStartup:
16 call foo
17 ret
deps/lld/test/COFF/subsystem-inference2.test created+54
...@@ -0,0 +1,54 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj 2>&1 | FileCheck -check-prefix=WARN %s
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# WARN: warning: found main and WinMain; defaulting to /subsystem:console
6# CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: B82A000000C3
17symbols:
18 - Name: .text
19 Value: 0
20 SectionNumber: 1
21 SimpleType: IMAGE_SYM_TYPE_NULL
22 ComplexType: IMAGE_SYM_DTYPE_NULL
23 StorageClass: IMAGE_SYM_CLASS_STATIC
24 SectionDefinition:
25 Length: 6
26 NumberOfRelocations: 0
27 NumberOfLinenumbers: 0
28 CheckSum: 0
29 Number: 0
30 - Name: main
31 Value: 0
32 SectionNumber: 1
33 SimpleType: IMAGE_SYM_TYPE_NULL
34 ComplexType: IMAGE_SYM_DTYPE_NULL
35 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
36 - Name: WinMain
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
42 - Name: mainCRTStartup
43 Value: 0
44 SectionNumber: 1
45 SimpleType: IMAGE_SYM_TYPE_NULL
46 ComplexType: IMAGE_SYM_DTYPE_NULL
47 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
48 - Name: WinMainCRTStartup
49 Value: 0
50 SectionNumber: 1
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_NULL
53 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
54...
deps/lld/test/COFF/thinlto-archives.ll+10-2
...@@ -6,9 +6,17 @@...@@ -6,9 +6,17 @@
6; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll6; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll
7; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj7; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj
8; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj8; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj
9; RUN: lld-link /out:%T/thinlto-archives/main.exe -entry:main \9; RUN: lld-link -out:%T/thinlto-archives/main.exe -entry:main \
10; RUN: -subsystem:console %T/thinlto-archives/main.obj \10; RUN: -lldsavetemps -subsystem:console %T/thinlto-archives/main.obj \
11; RUN: %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib11; RUN: %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib
12; RUN: FileCheck %s < %T/thinlto-archives/main.exe.resolution.txt
13
14; CHECK: {{/thinlto-archives/main.obj$}}
15; CHECK: {{^-r=.*/thinlto-archives/main.obj,main,px$}}
16; CHECK: {{/thinlto-archives/a.libbar.obj$}}
17; CHECK-NEXT: {{^-r=.*/thinlto-archives/a.libbar.obj,foo,p$}}
18; CHECK-NEXT: {{/thinlto-archives/b.libbar.obj$}}
19; CHECK-NEXT: {{^-r=.*/thinlto-archives/b.libbar.obj,bar,p$}}
1220
13target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"21target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
14target triple = "x86_64-pc-windows-msvc"22target triple = "x86_64-pc-windows-msvc"
deps/lld/test/COFF/undefined-symbol-cv.s+5-5
...@@ -2,19 +2,19 @@...@@ -2,19 +2,19 @@
2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
3# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s3# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
44
5# CHECK: error: undefined symbol: ?foo@@YAHXZ5# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
6# CHECK-NEXT: >>> referenced by file1.cpp:16# CHECK-NEXT: >>> referenced by file1.cpp:1
7# CHECK-NEXT: >>> {{.*}}.obj:(main)7# CHECK-NEXT: >>> {{.*}}.obj:(main)
8# CHECK-NEXT: >>> referenced by file1.cpp:28# CHECK-NEXT: >>> referenced by file1.cpp:2
9# CHECK-NEXT: >>> {{.*}}.obj:(main)9# CHECK-NEXT: >>> {{.*}}.obj:(main)
1010# CHECK-EMPTY:
11# CHECK: error: undefined symbol: ?bar@@YAHXZ11# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
12# CHECK-NEXT: >>> referenced by file2.cpp:312# CHECK-NEXT: >>> referenced by file2.cpp:3
13# CHECK-NEXT: >>> {{.*}}.obj:(main)13# CHECK-NEXT: >>> {{.*}}.obj:(main)
14# CHECK-NEXT: >>> referenced by file1.cpp:414# CHECK-NEXT: >>> referenced by file1.cpp:4
15# CHECK-NEXT: >>> {{.*}}.obj:(f1)15# CHECK-NEXT: >>> {{.*}}.obj:(f1)
1616# CHECK-EMPTY:
17# CHECK: error: undefined symbol: ?baz@@YAHXZ17# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ)
18# CHECK-NEXT: >>> referenced by file1.cpp:518# CHECK-NEXT: >>> referenced by file1.cpp:5
19# CHECK-NEXT: >>> {{.*}}.obj:(f2)19# CHECK-NEXT: >>> {{.*}}.obj:(f2)
2020
deps/lld/test/COFF/undefined-symbol.s+6-6
...@@ -2,15 +2,15 @@...@@ -2,15 +2,15 @@
2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
3# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s3# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
44
5# CHECK: error: undefined symbol: ?foo@@YAHXZ5# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
6# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)6# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
7# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)7# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
88# CHECK-EMPTY:
9# CHECK: error: undefined symbol: ?bar@@YAHXZ9# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
10# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)10# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
11# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)11# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
1212# CHECK-EMPTY:
13# CHECK: error: undefined symbol: ?baz@@YAHXZ13# CHECK-NEXT: error: undefined symbol: "__declspec(dllimport) int __cdecl baz(void)" (__imp_?baz@@YAHXZ)
14# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)14# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)
1515
16 .section .text,"xr",one_only,main16 .section .text,"xr",one_only,main
...@@ -27,4 +27,4 @@ f1:...@@ -27,4 +27,4 @@ f1:
27 .section .text,"xr",one_only,f227 .section .text,"xr",one_only,f2
28.globl f228.globl f2
29f2:29f2:
30 call "?baz@@YAHXZ"30 callq *"__imp_?baz@@YAHXZ"(%rip)
deps/lld/test/COFF/wholearchive.s+1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1# REQUIRES: x861# REQUIRES: x86
22
3# RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj3# RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj
4# RUN: rm -f %t.archive.lib
4# RUN: llvm-ar rcs %t.archive.lib %t.archive.obj5# RUN: llvm-ar rcs %t.archive.lib %t.archive.obj
5# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.main.obj6# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.main.obj
67
deps/lld/test/ELF/Inputs/bad-reloc-target.test created+21
...@@ -0,0 +1,21 @@
1--- !ELF
2FileHeader:
3 Class: ELFCLASS64
4 Data: ELFDATA2LSB
5 Type: ET_REL
6 Machine: EM_X86_64
7Sections:
8 - Name: .text
9 Type: SHT_PROGBITS
10 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
11 - Name: .rela.text
12 Type: SHT_RELA
13 Link: .symtab
14 Info: 99
15 Relocations:
16 - Offset: 0x0000000000000000
17 Symbol: foo
18 Type: R_X86_64_64
19Symbols:
20 Global:
21 - Name: foo
\ No newline at end of file
deps/lld/test/ELF/Inputs/copy-rel-tls.s created+12
...@@ -0,0 +1,12 @@
1.bss
2.global foo
3.type foo, @object
4.size foo, 4
5foo:
6
7.section .tbss,"awT",@nobits
8.global tfoo
9.skip 0x2000
10.type tfoo,@object
11.size tfoo, 4
12tfoo:
deps/lld/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s created+2
...@@ -0,0 +1,2 @@
1main:
2 callq f1
deps/lld/test/ELF/Inputs/gdb-index-multiple-cu-2.s created+45
...@@ -0,0 +1,45 @@
1.globl _start
2_start:
3
4.section .debug_abbrev,"",@progbits
5 .byte 1 # Abbreviation Code
6 .byte 17 # DW_TAG_compile_unit
7 .byte 1 # DW_CHILDREN_yes
8 .ascii "\264B" # DW_AT_GNU_pubnames
9 .byte 25 # DW_FORM_flag_present
10 .byte 0 # EOM(1)
11 .byte 0 # EOM(2)
12 .byte 2 # Abbreviation Code
13 .byte 46 # DW_TAG_subprogram
14 .byte 0 # DW_CHILDREN_no
15 .byte 3 # DW_AT_name
16 .byte 8 # DW_FORM_string
17 .byte 0 # EOM(1)
18 .byte 0 # EOM(2)
19 .byte 0
20
21.section .debug_info,"",@progbits
22.Lcu_begin0:
23 .long .Lcu_end0 - .Lcu_begin0 - 4
24 .short 4 # DWARF version number
25 .long 0 # Offset Into Abbrev. Section
26 .byte 4 # Address Size
27.Ldie:
28 .byte 1 # Abbrev [1] DW_TAG_compile_unit
29 .byte 2 # Abbrev [2] DW_TAG_subprogram
30 .asciz "_start" # DW_AT_name
31 .byte 0
32.Lcu_end0:
33
34# .debug_gnu_pubnames has just one set, associated with .Lcu_begin1 (CuIndex: 1)
35.section .debug_gnu_pubnames,"",@progbits
36 .long .LpubNames_end0 - .LpubNames_begin0
37.LpubNames_begin0:
38 .short 2 # Version
39 .long .Lcu_begin0 # CU Offset
40 .long .Lcu_end0 - .Lcu_begin0
41 .long .Ldie - .Lcu_begin0
42 .byte 48 # Attributes: FUNCTION, EXTERNAL
43 .asciz "_start" # External Name
44 .long 0
45.LpubNames_end0:
deps/lld/test/ELF/Inputs/hexagon-shared.s created+3
...@@ -0,0 +1,3 @@
1.global bar
2bar:
3 jumpr lr
deps/lld/test/ELF/Inputs/i386-linkonce.s created+11
...@@ -0,0 +1,11 @@
1.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
2.global __i686.get_pc_thunk.bx
3__i686.get_pc_thunk.bx:
4 mov (%esp),%ebx
5 ret
6
7.section .text
8.global _strchr1
9_strchr1:
10 call __i686.get_pc_thunk.bx
11 ret
deps/lld/test/ELF/Inputs/ppc64-bsymbolic-local-def.s created+14
...@@ -0,0 +1,14 @@
1 .abiversion 2
2 .section ".text"
3
4 .p2align 2
5 .global def
6 .type def, @function
7def:
8.Ldef_gep:
9 addis 2, 12, .TOC.-.Ldef_gep@ha
10 addi 2, 2, .TOC.-.Ldef_gep@l
11.Ldef_lep:
12 .localentry def, .-def
13 li 3, 55
14 blr
deps/lld/test/ELF/Inputs/ppc64-no-split-stack.s created+8
...@@ -0,0 +1,8 @@
1 .abiversion 2
2 .p2align 2
3 .global nss_callee
4 .type nss_callee, @function
5nss_callee:
6 li 3, 1
7 blr
8
deps/lld/test/ELF/Inputs/ppc64-tls-ie-le.s created+29
...@@ -0,0 +1,29 @@
1 .text
2 .abiversion 2
3 .type c,@object # @c
4 .section .tdata,"awT",@progbits
5 .globl c
6c:
7 .byte 97 # 0x61
8 .size c, 1
9
10 .type s,@object # @s
11 .globl s
12 .p2align 1
13s:
14 .short 55 # 0x37
15 .size s, 2
16
17 .type i,@object # @i
18 .globl i
19 .p2align 2
20i:
21 .long 55 # 0x37
22 .size i, 4
23
24 .type l,@object # @l
25 .globl l
26 .p2align 3
27l:
28 .quad 55 # 0x37
29 .size l, 8
deps/lld/test/ELF/Inputs/ppc64le-quadword-ldst.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/ppc64le-quadword-ldst.o differ
deps/lld/test/ELF/Inputs/wrap-with-archive.s created+5
...@@ -0,0 +1,5 @@
1.global __executable_start
2.global __wrap_get_executable_start
3
4__wrap_get_executable_start:
5 movabs $__executable_start,%rdx
deps/lld/test/ELF/Inputs/x86-64-split-stack-extra.s created+10
...@@ -0,0 +1,10 @@
1# This file is split out to provide better code coverage.
2 .global split
3 .type split,@function
4split:
5 retq
6
7 .size split,. - split
8
9 .section .note.GNU-stack,"",@progbits
10 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/aarch64-abs16.s+10-10
...@@ -14,14 +14,14 @@ _start:...@@ -14,14 +14,14 @@ _start:
14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1515
16// CHECK: Contents of section .data:16// CHECK: Contents of section .data:
17// 11000: S = 0x100, A = 0xfeff17// 210000: S = 0x100, A = 0xfeff
18// S + A = 0xffff18// S + A = 0xffff
19// 11002: S = 0x100, A = -0x810019// 210002: S = 0x100, A = -0x8100
20// S + A = 0x800020// S + A = 0x8000
21// CHECK-NEXT: 20000 ffff008021// CHECK-NEXT: 210000 ffff0080
2222
23// RUN: not ld.lld %t.o %t255.o -o %t223// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// | FileCheck %s --check-prefix=OVERFLOW24// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 32767]
25// RUN: not ld.lld %t.o %t257.o -o %t225
26// | FileCheck %s --check-prefix=OVERFLOW26// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
27// OVERFLOW: Relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]27// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 32767]
deps/lld/test/ELF/aarch64-abs32.s+10-10
...@@ -14,14 +14,14 @@ _start:...@@ -14,14 +14,14 @@ _start:
14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1515
16// CHECK: Contents of section .data:16// CHECK: Contents of section .data:
17// 20000: S = 0x100, A = 0xfffffeff17// 210000: S = 0x100, A = 0xfffffeff
18// S + A = 0xffffffff18// S + A = 0xffffffff
19// 20004: S = 0x100, A = -0x8000010019// 210004: S = 0x100, A = -0x80000100
20// S + A = 0x8000000020// S + A = 0x80000000
21// CHECK-NEXT: 20000 ffffffff 0000008021// CHECK-NEXT: 210000 ffffffff 00000080
2222
23// RUN: not ld.lld %t.o %t255.o -o %t223// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// | FileCheck %s --check-prefix=OVERFLOW24// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 2147483647]
25// RUN: not ld.lld %t.o %t257.o -o %t225
26// | FileCheck %s --check-prefix=OVERFLOW26// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
27// OVERFLOW: Relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]27// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 2147483647]
deps/lld/test/ELF/aarch64-call26-thunk.s+5-5
...@@ -11,11 +11,11 @@ _start:...@@ -11,11 +11,11 @@ _start:
1111
12// CHECK: Disassembly of section .text:12// CHECK: Disassembly of section .text:
13// CHECK-NEXT: _start:13// CHECK-NEXT: _start:
14// CHECK-NEXT: 20000: 02 00 00 94 bl #814// CHECK-NEXT: 210000: 02 00 00 94 bl #8
15// CHECK: __AArch64AbsLongThunk_big:15// CHECK: __AArch64AbsLongThunk_big:
16// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #816// CHECK-NEXT: 210008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 2000c: 00 02 1f d6 br x1617// CHECK-NEXT: 21000c: 00 02 1f d6 br x16
18// CHECK: $d:18// CHECK: $d:
19// CHECK-NEXT: 20010: 00 00 00 00 .word 0x0000000019// CHECK-NEXT: 210010: 00 00 00 00 .word 0x00000000
20// CHECK-NEXT: 20014: 10 00 00 00 .word 0x0000001020// CHECK-NEXT: 210014: 10 00 00 00 .word 0x00000010
2121
deps/lld/test/ELF/aarch64-combined-dynrel-ifunc.s created+51
...@@ -0,0 +1,51 @@
1// REQUIRES: AArch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/shared.s -o %t-lib.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
4// RUN: ld.lld %t-lib.o --shared -o %t.so
5// RUN: echo "SECTIONS { \
6// RUN: .text : { *(.text) } \
7// RUN: .rela.dyn : { *(.rela.dyn) *(.rela.plt) } \
8// RUN: } " > %t.script
9// RUN: ld.lld %t.o -o %t.axf %t.so --script %t.script
10// RUN: llvm-readobj --section-headers --dynamic-table %t.axf | FileCheck %s
11
12// The linker script above combines the .rela.dyn and .rela.plt into a single
13// table. ELF is clear that the DT_PLTRELSZ should match the subset of
14// relocations that is associated with the PLT. It is less clear about what
15// the value of DT_RELASZ should be. ELF implies that it should be the size
16// of the single table so that DT_RELASZ includes DT_PLTRELSZ. The loader in
17// glibc permits this as long as .rela.plt comes after .rela.dyn in the
18// combined table. In the ARM case irelative relocations do not count as PLT
19// relocs. In the AArch64 case irelative relocations count as PLT relocs.
20
21.text
22.globl indirect
23.type indirect,@gnu_indirect_function
24indirect:
25 ret
26
27.globl bar // from Inputs/shared.s
28
29.text
30.globl _start
31.type _start,@function
32main:
33 bl indirect
34 bl bar
35 adrp x8, :got:indirect
36 ldr x8, [x8, :got_lo12:indirect]
37 adrp x8, :got:bar
38 ldr x8, [x8, :got_lo12:bar]
39 ret
40
41// CHECK: Name: .rela.dyn
42// CHECK-NEXT: Type: SHT_RELA
43// CHECK-NEXT: Flags [
44// CHECK-NEXT: SHF_ALLOC
45// CHECK-NEXT: ]
46// CHECK-NEXT: Address:
47// CHECK-NEXT: Offset:
48// CHECK-NEXT: Size: 72
49
50// CHECK: 0x0000000000000008 RELASZ 72
51// CHECK: 0x0000000000000002 PLTRELSZ 48
deps/lld/test/ELF/aarch64-combined-dynrel.s created+41
...@@ -0,0 +1,41 @@
1// REQUIRES: AArch64
2// RUN: llvm-mc --triple=aarch64-linux-gnu -filetype=obj -o %t.o %s
3// RUN: echo "SECTIONS { \
4// RUN: .text : { *(.text) } \
5// RUN: .rela.dyn : { *(.rela.dyn) *(.rela.plt) } \
6// RUN: } " > %t.script
7// RUN: ld.lld %t.o -o %t.so --shared --script %t.script
8// RUN: llvm-readobj --section-headers --dynamic-table %t.so | FileCheck %s
9
10// The linker script above combines the .rela.dyn and .rela.plt into a single
11// table. ELF is clear that the DT_PLTRELSZ should match the subset of
12// relocations that is associated with the PLT. It is less clear about what
13// the value of DT_RELASZ should be. ELF implies that it should be the size
14// of the single table so that DT_RELASZ includes DT_PLTRELSZ. The loader in
15// glibc permits this as long as .rela.plt comes after .rela.dyn in the
16// combined table.
17 .text
18 .globl func
19 .type func, %function
20 .globl foo
21 .type foo, %object
22
23 .globl _start
24 .type _start, %function
25_start:
26 bl func
27 adrp x8, :got:foo
28 ldr x8, [x8, :got_lo12:foo]
29 ret
30
31// CHECK: Name: .rela.dyn
32// CHECK-NEXT: Type: SHT_RELA
33// CHECK-NEXT: Flags [
34// CHECK-NEXT: SHF_ALLOC
35// CHECK-NEXT: ]
36// CHECK-NEXT: Address:
37// CHECK-NEXT: Offset:
38// CHECK-NEXT: Size: 48
39
40// CHECK: 0x0000000000000008 RELASZ 48
41// CHECK: 0x0000000000000002 PLTRELSZ 24
deps/lld/test/ELF/aarch64-condb-reloc.s+18-12
...@@ -12,21 +12,21 @@...@@ -12,21 +12,21 @@
12# 0x1102c - 16 = 0x1101c12# 0x1102c - 16 = 0x1101c
13# CHECK: Disassembly of section .text:13# CHECK: Disassembly of section .text:
14# CHECK-NEXT: _foo:14# CHECK-NEXT: _foo:
15# CHECK-NEXT: 20000: {{.*}} nop15# CHECK-NEXT: 210000: {{.*}} nop
16# CHECK-NEXT: 20004: {{.*}} nop16# CHECK-NEXT: 210004: {{.*}} nop
17# CHECK-NEXT: 20008: {{.*}} nop17# CHECK-NEXT: 210008: {{.*}} nop
18# CHECK-NEXT: 2000c: {{.*}} nop18# CHECK-NEXT: 21000c: {{.*}} nop
19# CHECK: _bar:19# CHECK: _bar:
20# CHECK-NEXT: 20010: {{.*}} nop20# CHECK-NEXT: 210010: {{.*}} nop
21# CHECK-NEXT: 20014: {{.*}} nop21# CHECK-NEXT: 210014: {{.*}} nop
22# CHECK-NEXT: 20018: {{.*}} nop22# CHECK-NEXT: 210018: {{.*}} nop
23# CHECK: _dah:23# CHECK: _dah:
24# CHECK-NEXT: 2001c: {{.*}} nop24# CHECK-NEXT: 21001c: {{.*}} nop
25# CHECK-NEXT: 20020: {{.*}} nop25# CHECK-NEXT: 210020: {{.*}} nop
26# CHECK: _start:26# CHECK: _start:
27# CHECK-NEXT: 20024: {{.*}} b.eq #-3627# CHECK-NEXT: 210024: {{.*}} b.eq #-36
28# CHECK-NEXT: 20028: {{.*}} b.eq #-2428# CHECK-NEXT: 210028: {{.*}} b.eq #-24
29# CHECK-NEXT: 2002c: {{.*}} b.eq #-1629# CHECK-NEXT: 21002c: {{.*}} b.eq #-16
3030
31#DSOREL: Section {31#DSOREL: Section {
32#DSOREL: Index:32#DSOREL: Index:
...@@ -79,14 +79,20 @@...@@ -79,14 +79,20 @@
79#DSO-NEXT: 10044: {{.*}} nop79#DSO-NEXT: 10044: {{.*}} nop
80#DSO-NEXT: 10048: {{.*}} nop80#DSO-NEXT: 10048: {{.*}} nop
81#DSO-NEXT: 1004c: {{.*}} nop81#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-EMPTY:
83#DSO-NEXT: _foo@plt:
82#DSO-NEXT: 10050: {{.*}} adrp x16, #6553684#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
83#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]85#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
84#DSO-NEXT: 10058: {{.*}} add x16, x16, #2486#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
85#DSO-NEXT: 1005c: {{.*}} br x1787#DSO-NEXT: 1005c: {{.*}} br x17
88#DSO-EMPTY:
89#DSO-NEXT: _bar@plt:
86#DSO-NEXT: 10060: {{.*}} adrp x16, #6553690#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
87#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]91#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
88#DSO-NEXT: 10068: {{.*}} add x16, x16, #3292#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
89#DSO-NEXT: 1006c: {{.*}} br x1793#DSO-NEXT: 1006c: {{.*}} br x17
94#DSO-EMPTY:
95#DSO-NEXT: _dah@plt:
90#DSO-NEXT: 10070: {{.*}} adrp x16, #6553696#DSO-NEXT: 10070: {{.*}} adrp x16, #65536
91#DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40]97#DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40]
92#DSO-NEXT: 10078: {{.*}} add x16, x16, #4098#DSO-NEXT: 10078: {{.*}} add x16, x16, #40
deps/lld/test/ELF/aarch64-copy.s+16-16
...@@ -22,7 +22,7 @@ _start:...@@ -22,7 +22,7 @@ _start:
22// CHECK-NEXT: SHF_ALLOC22// CHECK-NEXT: SHF_ALLOC
23// CHECK-NEXT: SHF_WRITE23// CHECK-NEXT: SHF_WRITE
24// CHECK-NEXT: ]24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x4000025// CHECK-NEXT: Address: 0x230000
26// CHECK-NEXT: Offset:26// CHECK-NEXT: Offset:
27// CHECK-NEXT: Size: 2427// CHECK-NEXT: Size: 24
28// CHECK-NEXT: Link:28// CHECK-NEXT: Link:
...@@ -32,19 +32,19 @@ _start:...@@ -32,19 +32,19 @@ _start:
32// CHECK: Relocations [32// CHECK: Relocations [
33// CHECK-NEXT: Section ({{.*}}) .rela.dyn {33// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
34// CHECK-NEXT: Relocation {34// CHECK-NEXT: Relocation {
35// CHECK-NEXT: Offset: 0x4000035// CHECK-NEXT: Offset: 0x230000
36// CHECK-NEXT: Type: R_AARCH64_COPY36// CHECK-NEXT: Type: R_AARCH64_COPY
37// CHECK-NEXT: Symbol: x37// CHECK-NEXT: Symbol: x
38// CHECK-NEXT: Addend: 0x038// CHECK-NEXT: Addend: 0x0
39// CHECK-NEXT: }39// CHECK-NEXT: }
40// CHECK-NEXT: Relocation {40// CHECK-NEXT: Relocation {
41// CHECK-NEXT: Offset: 0x4001041// CHECK-NEXT: Offset: 0x230010
42// CHECK-NEXT: Type: R_AARCH64_COPY42// CHECK-NEXT: Type: R_AARCH64_COPY
43// CHECK-NEXT: Symbol: y43// CHECK-NEXT: Symbol: y
44// CHECK-NEXT: Addend: 0x044// CHECK-NEXT: Addend: 0x0
45// CHECK-NEXT: }45// CHECK-NEXT: }
46// CHECK-NEXT: Relocation {46// CHECK-NEXT: Relocation {
47// CHECK-NEXT: Offset: 0x4001447// CHECK-NEXT: Offset: 0x230014
48// CHECK-NEXT: Type: R_AARCH64_COPY48// CHECK-NEXT: Type: R_AARCH64_COPY
49// CHECK-NEXT: Symbol: z49// CHECK-NEXT: Symbol: z
50// CHECK-NEXT: Addend: 0x050// CHECK-NEXT: Addend: 0x0
...@@ -54,21 +54,21 @@ _start:...@@ -54,21 +54,21 @@ _start:
5454
55// CHECK: Symbols [55// CHECK: Symbols [
56// CHECK: Name: x56// CHECK: Name: x
57// CHECK-NEXT: Value: 0x4000057// CHECK-NEXT: Value: 0x230000
58// CHECK-NEXT: Size: 458// CHECK-NEXT: Size: 4
59// CHECK-NEXT: Binding: Global59// CHECK-NEXT: Binding: Global
60// CHECK-NEXT: Type: Object60// CHECK-NEXT: Type: Object
61// CHECK-NEXT: Other:61// CHECK-NEXT: Other:
62// CHECK-NEXT: Section: .bss62// CHECK-NEXT: Section: .bss
63// CHECK: Name: y63// CHECK: Name: y
64// CHECK-NEXT: Value: 0x4001064// CHECK-NEXT: Value: 0x230010
65// CHECK-NEXT: Size: 465// CHECK-NEXT: Size: 4
66// CHECK-NEXT: Binding: Global66// CHECK-NEXT: Binding: Global
67// CHECK-NEXT: Type: Object67// CHECK-NEXT: Type: Object
68// CHECK-NEXT: Other:68// CHECK-NEXT: Other:
69// CHECK-NEXT: Section: .bss69// CHECK-NEXT: Section: .bss
70// CHECK: Name: z70// CHECK: Name: z
71// CHECK-NEXT: Value: 0x4001471// CHECK-NEXT: Value: 0x230014
72// CHECK-NEXT: Size: 472// CHECK-NEXT: Size: 4
73// CHECK-NEXT: Binding: Global73// CHECK-NEXT: Binding: Global
74// CHECK-NEXT: Type: Object74// CHECK-NEXT: Type: Object
...@@ -78,16 +78,16 @@ _start:...@@ -78,16 +78,16 @@ _start:
7878
79// CODE: Disassembly of section .text:79// CODE: Disassembly of section .text:
80// CODE-NEXT: _start:80// CODE-NEXT: _start:
81// S(x) = 0x40000, A = 0, P = 0x2000081// S(x) = 0x230000, A = 0, P = 0x210000
82// S + A - P = 0x20000 = 13107282// S + A - P = 0x20000 = 131072
83// CODE-NEXT: 20000: {{.*}} adr x1, #13107283// CODE-NEXT: 210000: {{.*}} adr x1, #131072
84// S(y) = 0x40010, A = 0, P = 0x2000484// S(y) = 0x230010, A = 0, P = 0x210004
85// Page(S + A) - Page(P) = 0x40000 - 0x20000 = 0x20000 = 13107285// Page(S + A) - Page(P) = 0x230000 - 0x210000 = 0x20000 = 131072
86// CODE-NEXT: 20004: {{.*}} adrp x2, #13107286// CODE-NEXT: 210004: {{.*}} adrp x2, #131072
87// S(y) = 0x40010, A = 087// S(y) = 0x230010, A = 0
88// (S + A) & 0xFFF = 0x10 = 1688// (S + A) & 0xFFF = 0x10 = 16
89// CODE-NEXT: 20008: {{.*}} add x2, x2, #1689// CODE-NEXT: 210008: {{.*}} add x2, x2, #16
9090
91// RODATA: Contents of section .rodata:91// RODATA: Contents of section .rodata:
92// S(z) = 0x4001492// S(z) = 0x230014
93// RODATA-NEXT: 102e0 1400040093// RODATA-NEXT: 2002e0 14002300
deps/lld/test/ELF/aarch64-copy2.s+1-1
...@@ -19,7 +19,7 @@ _start:...@@ -19,7 +19,7 @@ _start:
19// CHECK-NEXT: Section: Undefined19// CHECK-NEXT: Section: Undefined
2020
21// CHECK: Name: foo21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x2003022// CHECK-NEXT: Value: 0x210030
23// CHECK-NEXT: Size: 023// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Global24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Function25// CHECK-NEXT: Type: Function
deps/lld/test/ELF/aarch64-cortex-a53-843419-abs-mapsyms.s created+22
...@@ -0,0 +1,22 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
3// RUN: ld.lld --just-symbols %t -fix-cortex-a53-843419 -o %t.axf
4// RUN: llvm-readobj --symbols %t.axf | FileCheck %s
5
6// Check that we can gracefully handle --just-symbols, which gives a local
7// absolute mapping symbol (with no Section). Previously we assumed that all
8// mapping symbols were defined relative to a section and assert failed.
9
10 .text
11 .global _start
12 .type _start, %function
13_start: ret
14
15// CHECK: Name: $x.0
16// CHECK-NEXT: Value: 0x0
17// CHECK-NEXT: Size: 0
18// CHECK-NEXT: Binding: Local (0x0)
19// CHECK-NEXT: Type: None (0x0)
20// CHECK-NEXT: Other: 0
21// CHECK-NEXT: Section: Absolute (0xFFF1)
22// CHECK-NEXT: }
deps/lld/test/ELF/aarch64-cortex-a53-843419-cli.s+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: not ld.lld %t -fix-cortex-a53-843419 -o /dev/null 2>&1 | FileCheck %s3// RUN: not ld.lld %t -fix-cortex-a53-843419 -o /dev/null 2>&1 | FileCheck %s
44
5// CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets.5// CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets
6.globl entry6.globl entry
7.text7.text
8 .quad 08 .quad 0
deps/lld/test/ELF/aarch64-cortex-a53-843419-large.s+37-37
...@@ -1,23 +1,23 @@...@@ -1,23 +1,23 @@
1// REQUIRES: aarch641// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
3// RUN: ld.lld --fix-cortex-a53-843419 %t.o -o %t23// RUN: ld.lld --fix-cortex-a53-843419 %t.o -o %t2
4// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=131072 -stop-address=131084 | FileCheck --check-prefix=CHECK1 %s4// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2162688 -stop-address=2162700 | FileCheck --check-prefix=CHECK1 %s
5// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=135168 -stop-address=135172 | FileCheck --check-prefix=CHECK2 %s5// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2166784 -stop-address=2166788 | FileCheck --check-prefix=CHECK2 %s
6// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=139256 -stop-address=139272 | FileCheck --check-prefix=CHECK3 %s6// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2170872 -stop-address=2170888 | FileCheck --check-prefix=CHECK3 %s
7// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=67256312 -stop-address=67256328 | FileCheck --check-prefix=CHECK4 %s7// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=69287928 -stop-address=69287944 | FileCheck --check-prefix=CHECK4 %s
8// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=100810760 -stop-address=100810776 | FileCheck --check-prefix=CHECK5 %s8// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=102842376 -stop-address=102842392 | FileCheck --check-prefix=CHECK5 %s
9// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134352908 -stop-address=134352912 | FileCheck --check-prefix=CHECK6 %s9// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=136384524 -stop-address=136384528 | FileCheck --check-prefix=CHECK6 %s
10// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134356988 -stop-address=134357012 | FileCheck --check-prefix=CHECK7 %s10// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=136388604 -stop-address=136388628 | FileCheck --check-prefix=CHECK7 %s
11// Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding11// Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding
12// the maximum branch range. Both range extension thunks and patches are12// the maximum branch range. Both range extension thunks and patches are
13// required.13// required.
1414
15// CHECK1: __AArch64AbsLongThunk_need_thunk_after_patch:15// CHECK1: __AArch64AbsLongThunk_need_thunk_after_patch:
16// CHECK1-NEXT: 20000: 50 00 00 58 ldr x16, #816// CHECK1-NEXT: 210000: 50 00 00 58 ldr x16, #8
17// CHECK1-NEXT: 20004: 00 02 1f d6 br x1617// CHECK1-NEXT: 210004: 00 02 1f d6 br x16
18// CHECK1: $d:18// CHECK1: $d:
19// CHECK1-NEXT: 20008: 0c 10 02 08 .word 0x0802100c19// CHECK1-NEXT: 210008: 0c 10 21 08 .word 0x0821100c
2020
21 .section .text.01, "ax", %progbits21 .section .text.01, "ax", %progbits
22 .balign 409622 .balign 4096
23 .globl _start23 .globl _start
...@@ -29,7 +29,7 @@ _start:...@@ -29,7 +29,7 @@ _start:
29 .space 4096 - 1229 .space 4096 - 12
3030
31// CHECK2: _start:31// CHECK2: _start:
32// CHECK2-NEXT: 21000: 00 fc ff 97 bl #-409632// CHECK2-NEXT: 211000: 00 fc ff 97 bl #-4096
3333
34 // Expect patch on pass 134 // Expect patch on pass 1
35 .section .text.03, "ax", %progbits35 .section .text.03, "ax", %progbits
...@@ -42,10 +42,10 @@ t3_ff8_ldr:...@@ -42,10 +42,10 @@ t3_ff8_ldr:
42 ret42 ret
4343
44// CHECK3: t3_ff8_ldr:44// CHECK3: t3_ff8_ldr:
45// CHECK3-NEXT: 21ff8: 60 00 04 f0 adrp x0, #13427916845// CHECK3-NEXT: 211ff8: 60 00 04 f0 adrp x0, #134279168
46// CHECK3-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1]46// CHECK3-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
47// CHECK3-NEXT: 22000: 02 08 80 15 b #10067149647// CHECK3-NEXT: 212000: 02 08 80 15 b #100671496
48// CHECK3-NEXT: 22004: c0 03 5f d6 ret48// CHECK3-NEXT: 212004: c0 03 5f d6 ret
4949
50 .section .text.04, "ax", %progbits50 .section .text.04, "ax", %progbits
51 .space 64 * 1024 * 102451 .space 64 * 1024 * 1024
...@@ -63,20 +63,20 @@ t3_ff8_str:...@@ -63,20 +63,20 @@ t3_ff8_str:
63 ret63 ret
6464
65// CHECK4: t3_ff8_str:65// CHECK4: t3_ff8_str:
66// CHECK4-NEXT: 4023ff8: 60 00 02 b0 adrp x0, #6716211266// CHECK4-NEXT: 4213ff8: 60 00 02 b0 adrp x0, #67162112
67// CHECK4-NEXT: 4023ffc: 21 00 40 f9 ldr x1, [x1]67// CHECK4-NEXT: 4213ffc: 21 00 40 f9 ldr x1, [x1]
68// CHECK4-NEXT: 4024000: 04 00 80 14 b #3355444868// CHECK4-NEXT: 4214000: 04 00 80 14 b #33554448
69// CHECK4-NEXT: 4024004: c0 03 5f d6 ret69// CHECK4-NEXT: 4214004: c0 03 5f d6 ret
7070
71 .section .text.06, "ax", %progbits71 .section .text.06, "ax", %progbits
72 .space 32 * 1024 * 102472 .space 32 * 1024 * 1024
7373
74// CHECK5: __CortexA53843419_21000:74// CHECK5: __CortexA53843419_211000:
75// CHECK5-NEXT: 6024008: 00 00 40 f9 ldr x0, [x0]75// CHECK5-NEXT: 6214008: 00 00 40 f9 ldr x0, [x0]
76// CHECK5-NEXT: 602400c: fe f7 7f 16 b #-10067149676// CHECK5-NEXT: 621400c: fe f7 7f 16 b #-100671496
77// CHECK5: __CortexA53843419_4023000:77// CHECK5: __CortexA53843419_4213000:
78// CHECK5-NEXT: 6024010: 00 00 00 f9 str x0, [x0]78// CHECK5-NEXT: 6214010: 00 00 00 f9 str x0, [x0]
79// CHECK5-NEXT: 6024014: fc ff 7f 17 b #-3355444879// CHECK5-NEXT: 6214014: fc ff 7f 17 b #-33554448
8080
81 .section .text.07, "ax", %progbits81 .section .text.07, "ax", %progbits
82 .space (32 * 1024 * 1024) - 1230082 .space (32 * 1024 * 1024) - 12300
...@@ -88,7 +88,7 @@ need_thunk_after_patch:...@@ -88,7 +88,7 @@ need_thunk_after_patch:
88 ret88 ret
8989
90// CHECK6: need_thunk_after_patch:90// CHECK6: need_thunk_after_patch:
91// CHECK6-NEXT: 802100c: c0 03 5f d6 ret91// CHECK6-NEXT: 821100c: c0 03 5f d6 ret
9292
93 // Will need a patch on pass 293 // Will need a patch on pass 2
94 .section .text.09, "ax", %progbits94 .section .text.09, "ax", %progbits
...@@ -102,13 +102,13 @@ t3_ffc_ldr:...@@ -102,13 +102,13 @@ t3_ffc_ldr:
102 ret102 ret
103103
104// CHECK7: t3_ffc_ldr:104// CHECK7: t3_ffc_ldr:
105// CHECK7-NEXT: 8021ffc: 60 00 00 f0 adrp x0, #61440105// CHECK7-NEXT: 8211ffc: 60 00 00 f0 adrp x0, #61440
106// CHECK7-NEXT: 8022000: 21 00 40 f9 ldr x1, [x1]106// CHECK7-NEXT: 8212000: 21 00 40 f9 ldr x1, [x1]
107// CHECK7-NEXT: 8022004: 02 00 00 14 b #8107// CHECK7-NEXT: 8212004: 02 00 00 14 b #8
108// CHECK7-NEXT: 8022008: c0 03 5f d6 ret108// CHECK7-NEXT: 8212008: c0 03 5f d6 ret
109// CHECK7: __CortexA53843419_8022004:109// CHECK7: __CortexA53843419_8212004:
110// CHECK7-NEXT: 802200c: 00 00 40 f9 ldr x0, [x0]110// CHECK7-NEXT: 821200c: 00 00 40 f9 ldr x0, [x0]
111// CHECK7-NEXT: 8022010: fe ff ff 17 b #-8111// CHECK7-NEXT: 8212010: fe ff ff 17 b #-8
112112
113 .section .data113 .section .data
114 .globl dat114 .globl dat
deps/lld/test/ELF/aarch64-cortex-a53-843419-large2.s created+19
...@@ -0,0 +1,19 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
3// RUN: ld.lld --fix-cortex-a53-843419 -Ttext=0x8000000 %t.o -o %t2
4// RUN: llvm-objdump -d --start-address=0x8001000 --stop-address=0x8001004 %t2 | FileCheck %s
5
6.section .text.01, "ax", %progbits
7.balign 4096
8.space 4096 - 8
9adrp x0, thunk
10ldr x1, [x1, #0]
11// CHECK: thunk:
12// CHECK-NEXT: b #67108872 <__CortexA53843419_8001000>
13thunk:
14ldr x0, [x0, :got_lo12:thunk]
15ret
16.space 64 * 1024 * 1024
17
18.section .text.02, "ax", %progbits
19.space 64 * 1024 * 1024
deps/lld/test/ELF/aarch64-cortex-a53-843419-recognize.s+245-245
...@@ -26,13 +26,13 @@...@@ -26,13 +26,13 @@
26// - Optional instruction 3 present or not.26// - Optional instruction 3 present or not.
27// - Load or store for instruction 4.27// - Load or store for instruction 4.
2828
29// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FF8 in unpatched output.29// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 211FF8 in unpatched output.
30// CHECK: t3_ff8_ldr:30// CHECK: t3_ff8_ldr:
31// CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #25804831// CHECK-NEXT: 211ff8: e0 01 00 f0 adrp x0, #258048
32// CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1]32// CHECK-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
33// CHECK-FIX: 22000: 03 c8 00 14 b #20481233// CHECK-FIX: 212000: 03 c8 00 14 b #204812
34// CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0]34// CHECK-NOFIX: 212000: 00 00 40 f9 ldr x0, [x0]
35// CHECK-NEXT: 22004: c0 03 5f d6 ret35// CHECK-NEXT: 212004: c0 03 5f d6 ret
36 .section .text.01, "ax", %progbits36 .section .text.01, "ax", %progbits
37 .balign 409637 .balign 4096
38 .globl t3_ff8_ldr38 .globl t3_ff8_ldr
...@@ -44,13 +44,13 @@ t3_ff8_ldr:...@@ -44,13 +44,13 @@ t3_ff8_ldr:
44 ldr x0, [x0, :got_lo12:dat1]44 ldr x0, [x0, :got_lo12:dat1]
45 ret45 ret
4646
47// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FF8 in unpatched output.47// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 213FF8 in unpatched output.
48// CHECK: t3_ff8_ldrsimd:48// CHECK: t3_ff8_ldrsimd:
49// CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #24985649// CHECK-NEXT: 213ff8: e0 01 00 b0 adrp x0, #249856
50// CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1]50// CHECK-NEXT: 213ffc: 21 00 40 bd ldr s1, [x1]
51// CHECK-FIX: 24000: 05 c0 00 14 b #19662851// CHECK-FIX: 214000: 05 c0 00 14 b #196628
52// CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8]52// CHECK-NOFIX: 214000: 02 04 40 f9 ldr x2, [x0, #8]
53// CHECK-NEXT: 24004: c0 03 5f d6 ret53// CHECK-NEXT: 214004: c0 03 5f d6 ret
54 .section .text.02, "ax", %progbits54 .section .text.02, "ax", %progbits
55 .balign 409655 .balign 4096
56 .globl t3_ff8_ldrsimd56 .globl t3_ff8_ldrsimd
...@@ -62,13 +62,13 @@ t3_ff8_ldrsimd:...@@ -62,13 +62,13 @@ t3_ff8_ldrsimd:
62 ldr x2, [x0, :got_lo12:dat2]62 ldr x2, [x0, :got_lo12:dat2]
63 ret63 ret
6464
65// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 25FFC in unpatched output.65// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 215FFC in unpatched output.
66// CHECK: t3_ffc_ldrpost:66// CHECK: t3_ffc_ldrpost:
67// CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #24166467// CHECK-NEXT: 215ffc: c0 01 00 f0 adrp x0, #241664
68// CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #868// CHECK-NEXT: 216000: 21 84 40 bc ldr s1, [x1], #8
69// CHECK-FIX: 26004: 06 b8 00 14 b #18844069// CHECK-FIX: 216004: 06 b8 00 14 b #188440
70// CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16]70// CHECK-NOFIX: 216004: 03 08 40 f9 ldr x3, [x0, #16]
71// CHECK-NEXT: 26008: c0 03 5f d6 ret71// CHECK-NEXT: 216008: c0 03 5f d6 ret
72 .section .text.03, "ax", %progbits72 .section .text.03, "ax", %progbits
73 .balign 409673 .balign 4096
74 .globl t3_ffc_ldrpost74 .globl t3_ffc_ldrpost
...@@ -80,13 +80,13 @@ t3_ffc_ldrpost:...@@ -80,13 +80,13 @@ t3_ffc_ldrpost:
80 ldr x3, [x0, :got_lo12:dat3]80 ldr x3, [x0, :got_lo12:dat3]
81 ret81 ret
8282
83// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 27FF8 in unpatched output.83// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 217FF8 in unpatched output.
84// CHECK: t3_ff8_strpre:84// CHECK: t3_ff8_strpre:
85// CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #23347285// CHECK-NEXT: 217ff8: c0 01 00 b0 adrp x0, #233472
86// CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]!86// CHECK-NEXT: 217ffc: 21 8c 00 bc str s1, [x1, #8]!
87// CHECK-FIX: 28000: 09 b0 00 14 b #18026087// CHECK-FIX: 218000: 09 b0 00 14 b #180260
88// CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0]88// CHECK-NOFIX: 218000: 02 00 40 f9 ldr x2, [x0]
89// CHECK-NEXT: 28004: c0 03 5f d6 ret89// CHECK-NEXT: 218004: c0 03 5f d6 ret
90 .section .text.04, "ax", %progbits90 .section .text.04, "ax", %progbits
91 .balign 409691 .balign 4096
92 .globl t3_ff8_strpre92 .globl t3_ff8_strpre
...@@ -98,13 +98,13 @@ t3_ff8_strpre:...@@ -98,13 +98,13 @@ t3_ff8_strpre:
98 ldr x2, [x0, :lo12:dat1]98 ldr x2, [x0, :lo12:dat1]
99 ret99 ret
100100
101// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 29FFC in unpatched output.101// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 219FFC in unpatched output.
102// CHECK: t3_ffc_str:102// CHECK: t3_ffc_str:
103// CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280103// CHECK-NEXT: 219ffc: bc 01 00 f0 adrp x28, #225280
104// CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2]104// CHECK-NEXT: 21a000: 42 00 00 f9 str x2, [x2]
105// CHECK-FIX: 2a004: 0a a8 00 14 b #172072105// CHECK-FIX: 21a004: 0a a8 00 14 b #172072
106// CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8]106// CHECK-NOFIX: 21a004: 9c 07 00 f9 str x28, [x28, #8]
107// CHECK-NEXT: 2a008: c0 03 5f d6 ret107// CHECK-NEXT: 21a008: c0 03 5f d6 ret
108 .section .text.05, "ax", %progbits108 .section .text.05, "ax", %progbits
109 .balign 4096109 .balign 4096
110 .globl t3_ffc_str110 .globl t3_ffc_str
...@@ -116,13 +116,13 @@ t3_ffc_str:...@@ -116,13 +116,13 @@ t3_ffc_str:
116 str x28, [x28, :lo12:dat2]116 str x28, [x28, :lo12:dat2]
117 ret117 ret
118118
119// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2BFFC in unpatched output.119// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21BFFC in unpatched output.
120// CHECK: t3_ffc_strsimd:120// CHECK: t3_ffc_strsimd:
121// CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088121// CHECK-NEXT: 21bffc: bc 01 00 b0 adrp x28, #217088
122// CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2]122// CHECK-NEXT: 21c000: 44 00 00 b9 str w4, [x2]
123// CHECK-FIX: 2c004: 0c a0 00 14 b #163888123// CHECK-FIX: 21c004: 0c a0 00 14 b #163888
124// CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16]124// CHECK-NOFIX: 21c004: 84 0b 00 f9 str x4, [x28, #16]
125// CHECK-NEXT: 2c008: c0 03 5f d6 ret125// CHECK-NEXT: 21c008: c0 03 5f d6 ret
126 .section .text.06, "ax", %progbits126 .section .text.06, "ax", %progbits
127 .balign 4096127 .balign 4096
128 .globl t3_ffc_strsimd128 .globl t3_ffc_strsimd
...@@ -134,13 +134,13 @@ t3_ffc_strsimd:...@@ -134,13 +134,13 @@ t3_ffc_strsimd:
134 str x4, [x28, :lo12:dat3]134 str x4, [x28, :lo12:dat3]
135 ret135 ret
136136
137// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2DFF8 in unpatched output.137// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21DFF8 in unpatched output.
138// CHECK: t3_ff8_ldrunpriv:138// CHECK: t3_ff8_ldrunpriv:
139// CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896139// CHECK-NEXT: 21dff8: 9d 01 00 f0 adrp x29, #208896
140// CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2]140// CHECK-NEXT: 21dffc: 41 08 40 38 ldtrb w1, [x2]
141// CHECK-FIX: 2e000: 0f 98 00 14 b #155708141// CHECK-FIX: 21e000: 0f 98 00 14 b #155708
142// CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29]142// CHECK-NOFIX: 21e000: bd 03 40 f9 ldr x29, [x29]
143// CHECK-NEXT: 2e004: c0 03 5f d6 ret143// CHECK-NEXT: 21e004: c0 03 5f d6 ret
144 .section .text.07, "ax", %progbits144 .section .text.07, "ax", %progbits
145 .balign 4096145 .balign 4096
146 .globl t3_ff8_ldrunpriv146 .globl t3_ff8_ldrunpriv
...@@ -152,13 +152,13 @@ t3_ff8_ldrunpriv:...@@ -152,13 +152,13 @@ t3_ff8_ldrunpriv:
152 ldr x29, [x29, :got_lo12:dat1]152 ldr x29, [x29, :got_lo12:dat1]
153 ret153 ret
154154
155// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2FFFC in unpatched output.155// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FFFC in unpatched output.
156// CHECK: t3_ffc_ldur:156// CHECK: t3_ffc_ldur:
157// CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704157// CHECK-NEXT: 21fffc: 9d 01 00 b0 adrp x29, #200704
158// CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4]158// CHECK-NEXT: 220000: 42 40 40 b8 ldur w2, [x2, #4]
159// CHECK-FIX: 30004: 10 90 00 14 b #147520159// CHECK-FIX: 220004: 10 90 00 14 b #147520
160// CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8]160// CHECK-NOFIX: 220004: bd 07 40 f9 ldr x29, [x29, #8]
161// CHECK-NEXT: 30008: c0 03 5f d6 ret161// CHECK-NEXT: 220008: c0 03 5f d6 ret
162 .balign 4096162 .balign 4096
163 .globl t3_ffc_ldur163 .globl t3_ffc_ldur
164 .type t3_ffc_ldur, %function164 .type t3_ffc_ldur, %function
...@@ -169,13 +169,13 @@ t3_ffc_ldur:...@@ -169,13 +169,13 @@ t3_ffc_ldur:
169 ldr x29, [x29, :got_lo12:dat2]169 ldr x29, [x29, :got_lo12:dat2]
170 ret170 ret
171171
172// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 31FFC in unpatched output.172// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 221FFC in unpatched output.
173// CHECK: t3_ffc_sturh:173// CHECK: t3_ffc_sturh:
174// CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512174// CHECK-NEXT: 221ffc: 72 01 00 f0 adrp x18, #192512
175// CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4]175// CHECK-NEXT: 222000: 43 40 00 78 sturh w3, [x2, #4]
176// CHECK-FIX: 32004: 12 88 00 14 b #139336176// CHECK-FIX: 222004: 12 88 00 14 b #139336
177// CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16]177// CHECK-NOFIX: 222004: 41 0a 40 f9 ldr x1, [x18, #16]
178// CHECK-NEXT: 32008: c0 03 5f d6 ret178// CHECK-NEXT: 222008: c0 03 5f d6 ret
179 .section .text.09, "ax", %progbits179 .section .text.09, "ax", %progbits
180 .balign 4096180 .balign 4096
181 .globl t3_ffc_sturh181 .globl t3_ffc_sturh
...@@ -187,13 +187,13 @@ t3_ffc_sturh:...@@ -187,13 +187,13 @@ t3_ffc_sturh:
187 ldr x1, [x18, :got_lo12:dat3]187 ldr x1, [x18, :got_lo12:dat3]
188 ret188 ret
189189
190// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 33FF8 in unpatched output.190// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 223FF8 in unpatched output.
191// CHECK: t3_ff8_literal:191// CHECK: t3_ff8_literal:
192// CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320192// CHECK-NEXT: 223ff8: 72 01 00 b0 adrp x18, #184320
193// CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4193// CHECK-NEXT: 223ffc: e3 ff ff 58 ldr x3, #-4
194// CHECK-FIX: 34000: 15 80 00 14 b #131156194// CHECK-FIX: 224000: 15 80 00 14 b #131156
195// CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18]195// CHECK-NOFIX: 224000: 52 02 40 f9 ldr x18, [x18]
196// CHECK-NEXT: 34004: c0 03 5f d6 ret196// CHECK-NEXT: 224004: c0 03 5f d6 ret
197 .section .text.10, "ax", %progbits197 .section .text.10, "ax", %progbits
198 .balign 4096198 .balign 4096
199 .globl t3_ff8_literal199 .globl t3_ff8_literal
...@@ -205,13 +205,13 @@ t3_ff8_literal:...@@ -205,13 +205,13 @@ t3_ff8_literal:
205 ldr x18, [x18, :lo12:dat1]205 ldr x18, [x18, :lo12:dat1]
206 ret206 ret
207207
208// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 35FFC in unpatched output.208// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 225FFC in unpatched output.
209// CHECK: t3_ffc_register:209// CHECK: t3_ffc_register:
210// CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128210// CHECK-NEXT: 225ffc: 4f 01 00 f0 adrp x15, #176128
211// CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1]211// CHECK-NEXT: 226000: 43 68 61 f8 ldr x3, [x2, x1]
212// CHECK-FIX: 36004: 16 78 00 14 b #122968212// CHECK-FIX: 226004: 16 78 00 14 b #122968
213// CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8]213// CHECK-NOFIX: 226004: ea 05 40 f9 ldr x10, [x15, #8]
214// CHECK-NEXT: 36008: c0 03 5f d6 ret214// CHECK-NEXT: 226008: c0 03 5f d6 ret
215 .section .text.11, "ax", %progbits215 .section .text.11, "ax", %progbits
216 .balign 4096216 .balign 4096
217 .globl t3_ffc_register217 .globl t3_ffc_register
...@@ -223,13 +223,13 @@ t3_ffc_register:...@@ -223,13 +223,13 @@ t3_ffc_register:
223 ldr x10, [x15, :lo12:dat2]223 ldr x10, [x15, :lo12:dat2]
224 ret224 ret
225225
226// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 37FF8 in unpatched output.226// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 227FF8 in unpatched output.
227// CHECK: t3_ff8_stp:227// CHECK: t3_ff8_stp:
228// CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936228// CHECK-NEXT: 227ff8: 50 01 00 b0 adrp x16, #167936
229// CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3]229// CHECK-NEXT: 227ffc: 61 08 00 a9 stp x1, x2, [x3]
230// CHECK-FIX: 38000: 19 70 00 14 b #114788230// CHECK-FIX: 228000: 19 70 00 14 b #114788
231// CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16]231// CHECK-NOFIX: 228000: 0d 0a 40 f9 ldr x13, [x16, #16]
232// CHECK-NEXT: 38004: c0 03 5f d6 ret232// CHECK-NEXT: 228004: c0 03 5f d6 ret
233 .section .text.12, "ax", %progbits233 .section .text.12, "ax", %progbits
234 .balign 4096234 .balign 4096
235 .globl t3_ff8_stp235 .globl t3_ff8_stp
...@@ -241,13 +241,13 @@ t3_ff8_stp:...@@ -241,13 +241,13 @@ t3_ff8_stp:
241 ldr x13, [x16, :lo12:dat3]241 ldr x13, [x16, :lo12:dat3]
242 ret242 ret
243243
244// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 39FFC in unpatched output.244// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 229FFC in unpatched output.
245// CHECK: t3_ffc_stnp:245// CHECK: t3_ffc_stnp:
246// CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744246// CHECK-NEXT: 229ffc: 27 01 00 f0 adrp x7, #159744
247// CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3]247// CHECK-NEXT: 22a000: 61 08 00 a8 stnp x1, x2, [x3]
248// CHECK-FIX: 3a004: 1a 68 00 14 b #106600248// CHECK-FIX: 22a004: 1a 68 00 14 b #106600
249// CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7]249// CHECK-NOFIX: 22a004: e9 00 40 f9 ldr x9, [x7]
250// CHECK-NEXT: 3a008: c0 03 5f d6 ret250// CHECK-NEXT: 22a008: c0 03 5f d6 ret
251 .section .text.13, "ax", %progbits251 .section .text.13, "ax", %progbits
252 .balign 4096252 .balign 4096
253 .globl t3_ffc_stnp253 .globl t3_ffc_stnp
...@@ -259,13 +259,13 @@ t3_ffc_stnp:...@@ -259,13 +259,13 @@ t3_ffc_stnp:
259 ldr x9, [x7, :lo12:dat1]259 ldr x9, [x7, :lo12:dat1]
260 ret260 ret
261261
262// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output.262// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22BFFC in unpatched output.
263// CHECK: t3_ffc_st1singlepost:263// CHECK: t3_ffc_st1singlepost:
264// CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552264// CHECK-NEXT: 22bffc: 37 01 00 b0 adrp x23, #151552
265// CHECK-NEXT: 3c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2265// CHECK-NEXT: 22c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2
266// CHECK-FIX: 3c004: 1c 60 00 14 b #98416266// CHECK-FIX: 22c004: 1c 60 00 14 b #98416
267// CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8]267// CHECK-NOFIX: 22c004: f6 06 40 f9 ldr x22, [x23, #8]
268// CHECK-NEXT: 3c008: c0 03 5f d6 ret268// CHECK-NEXT: 22c008: c0 03 5f d6 ret
269 .section .text.14, "ax", %progbits269 .section .text.14, "ax", %progbits
270 .balign 4096270 .balign 4096
271 .globl t3_ffc_st1singlepost271 .globl t3_ffc_st1singlepost
...@@ -277,13 +277,13 @@ t3_ffc_st1singlepost:...@@ -277,13 +277,13 @@ t3_ffc_st1singlepost:
277 ldr x22, [x23, :lo12:dat2]277 ldr x22, [x23, :lo12:dat2]
278 ret278 ret
279279
280// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3DFF8 in unpatched output.280// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22DFF8 in unpatched output.
281// CHECK: t3_ff8_st1multiple:281// CHECK: t3_ff8_st1multiple:
282// CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360282// CHECK-NEXT: 22dff8: 17 01 00 f0 adrp x23, #143360
283// CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1]283// CHECK-NEXT: 22dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1]
284// CHECK-FIX: 3e000: 1f 58 00 14 b #90236284// CHECK-FIX: 22e000: 1f 58 00 14 b #90236
285// CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16]285// CHECK-NOFIX: 22e000: f8 0a 40 f9 ldr x24, [x23, #16]
286// CHECK-NEXT: 3e004: c0 03 5f d6 ret286// CHECK-NEXT: 22e004: c0 03 5f d6 ret
287 .section .text.15, "ax", %progbits287 .section .text.15, "ax", %progbits
288 .balign 4096288 .balign 4096
289 .globl t3_ff8_st1multiple289 .globl t3_ff8_st1multiple
...@@ -295,14 +295,14 @@ t3_ff8_st1multiple:...@@ -295,14 +295,14 @@ t3_ff8_st1multiple:
295 ldr x24, [x23, :lo12:dat3]295 ldr x24, [x23, :lo12:dat3]
296 ret296 ret
297297
298// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3FFF8 in unpatched output.298// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22FFF8 in unpatched output.
299// CHECK: t4_ff8_ldr:299// CHECK: t4_ff8_ldr:
300// CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168300// CHECK-NEXT: 22fff8: 00 01 00 b0 adrp x0, #135168
301// CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1]301// CHECK-NEXT: 22fffc: 21 00 40 f9 ldr x1, [x1]
302// CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0302// CHECK-NEXT: 230000: 42 00 00 8b add x2, x2, x0
303// CHECK-FIX: 40004: 20 50 00 14 b #82048303// CHECK-FIX: 230004: 20 50 00 14 b #82048
304// CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0]304// CHECK-NOFIX: 230004: 02 00 40 f9 ldr x2, [x0]
305// CHECK-NEXT: 40008: c0 03 5f d6 ret305// CHECK-NEXT: 230008: c0 03 5f d6 ret
306 .section .text.16, "ax", %progbits306 .section .text.16, "ax", %progbits
307 .balign 4096307 .balign 4096
308 .globl t4_ff8_ldr308 .globl t4_ff8_ldr
...@@ -315,14 +315,14 @@ t4_ff8_ldr:...@@ -315,14 +315,14 @@ t4_ff8_ldr:
315 ldr x2, [x0, :got_lo12:dat1]315 ldr x2, [x0, :got_lo12:dat1]
316 ret316 ret
317317
318// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 41FFC in unpatched output.318// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 231FFC in unpatched output.
319// CHECK: t4_ffc_str:319// CHECK: t4_ffc_str:
320// CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976320// CHECK-NEXT: 231ffc: fc 00 00 f0 adrp x28, #126976
321// CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2]321// CHECK-NEXT: 232000: 42 00 00 f9 str x2, [x2]
322// CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2322// CHECK-NEXT: 232004: 20 00 02 cb sub x0, x1, x2
323// CHECK-FIX: 42008: 21 48 00 14 b #73860323// CHECK-FIX: 232008: 21 48 00 14 b #73860
324// CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8]324// CHECK-NOFIX: 232008: 9b 07 00 f9 str x27, [x28, #8]
325// CHECK-NEXT: 4200c: c0 03 5f d6 ret325// CHECK-NEXT: 23200c: c0 03 5f d6 ret
326 .section .text.17, "ax", %progbits326 .section .text.17, "ax", %progbits
327 .balign 4096327 .balign 4096
328 .globl t4_ffc_str328 .globl t4_ffc_str
...@@ -335,14 +335,14 @@ t4_ffc_str:...@@ -335,14 +335,14 @@ t4_ffc_str:
335 str x27, [x28, :got_lo12:dat2]335 str x27, [x28, :got_lo12:dat2]
336 ret336 ret
337337
338// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 43FF8 in unpatched output.338// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 233FF8 in unpatched output.
339// CHECK: t4_ff8_stp:339// CHECK: t4_ff8_stp:
340// CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784340// CHECK-NEXT: 233ff8: f0 00 00 b0 adrp x16, #118784
341// CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3]341// CHECK-NEXT: 233ffc: 61 08 00 a9 stp x1, x2, [x3]
342// CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16342// CHECK-NEXT: 234000: 03 7e 10 9b mul x3, x16, x16
343// CHECK-FIX: 44004: 24 40 00 14 b #65680343// CHECK-FIX: 234004: 24 40 00 14 b #65680
344// CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16]344// CHECK-NOFIX: 234004: 0e 0a 40 f9 ldr x14, [x16, #16]
345// CHECK-NEXT: 44008: c0 03 5f d6 ret345// CHECK-NEXT: 234008: c0 03 5f d6 ret
346 .section .text.18, "ax", %progbits346 .section .text.18, "ax", %progbits
347 .balign 4096347 .balign 4096
348 .globl t4_ff8_stp348 .globl t4_ff8_stp
...@@ -355,14 +355,14 @@ t4_ff8_stp:...@@ -355,14 +355,14 @@ t4_ff8_stp:
355 ldr x14, [x16, :got_lo12:dat3]355 ldr x14, [x16, :got_lo12:dat3]
356 ret356 ret
357357
358// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 45FF8 in unpatched output.358// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 235FF8 in unpatched output.
359// CHECK: t4_ff8_stppre:359// CHECK: t4_ff8_stppre:
360// CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592360// CHECK-NEXT: 235ff8: d0 00 00 f0 adrp x16, #110592
361// CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]!361// CHECK-NEXT: 235ffc: 61 08 81 a9 stp x1, x2, [x3, #16]!
362// CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16362// CHECK-NEXT: 236000: 03 7e 10 9b mul x3, x16, x16
363// CHECK-FIX: 46004: 26 38 00 14 b #57496363// CHECK-FIX: 236004: 26 38 00 14 b #57496
364// CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8]364// CHECK-NOFIX: 236004: 0e 06 40 f9 ldr x14, [x16, #8]
365// CHECK-NEXT: 46008: c0 03 5f d6 ret365// CHECK-NEXT: 236008: c0 03 5f d6 ret
366 .section .text.19, "ax", %progbits366 .section .text.19, "ax", %progbits
367 .balign 4096367 .balign 4096
368 .globl t4_ff8_stppre368 .globl t4_ff8_stppre
...@@ -375,14 +375,14 @@ t4_ff8_stppre:...@@ -375,14 +375,14 @@ t4_ff8_stppre:
375 ldr x14, [x16, #8]375 ldr x14, [x16, #8]
376 ret376 ret
377377
378// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 47FF8 in unpatched output.378// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 237FF8 in unpatched output.
379// CHECK: t4_ff8_stppost:379// CHECK: t4_ff8_stppost:
380// CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400380// CHECK-NEXT: 237ff8: d0 00 00 b0 adrp x16, #102400
381// CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16381// CHECK-NEXT: 237ffc: 61 08 81 a8 stp x1, x2, [x3], #16
382// CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16382// CHECK-NEXT: 238000: 03 7e 10 9b mul x3, x16, x16
383// CHECK-FIX: 48004: 28 30 00 14 b #49312383// CHECK-FIX: 238004: 28 30 00 14 b #49312
384// CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8]384// CHECK-NOFIX: 238004: 0e 06 40 f9 ldr x14, [x16, #8]
385// CHECK-NEXT: 48008: c0 03 5f d6 ret385// CHECK-NEXT: 238008: c0 03 5f d6 ret
386 .section .text.20, "ax", %progbits386 .section .text.20, "ax", %progbits
387 .balign 4096387 .balign 4096
388 .globl t4_ff8_stppost388 .globl t4_ff8_stppost
...@@ -395,14 +395,14 @@ t4_ff8_stppost:...@@ -395,14 +395,14 @@ t4_ff8_stppost:
395 ldr x14, [x16, #8]395 ldr x14, [x16, #8]
396 ret396 ret
397397
398// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 49FFC in unpatched output.398// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 239FFC in unpatched output.
399// CHECK: t4_ffc_stpsimd:399// CHECK: t4_ffc_stpsimd:
400// CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208400// CHECK-NEXT: 239ffc: b0 00 00 f0 adrp x16, #94208
401// CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3]401// CHECK-NEXT: 23a000: 61 08 00 ad stp q1, q2, [x3]
402// CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16402// CHECK-NEXT: 23a004: 03 7e 10 9b mul x3, x16, x16
403// CHECK-FIX: 4a008: 29 28 00 14 b #41124403// CHECK-FIX: 23a008: 29 28 00 14 b #41124
404// CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8]404// CHECK-NOFIX: 23a008: 0e 06 40 f9 ldr x14, [x16, #8]
405// CHECK-NEXT: 4a00c: c0 03 5f d6 ret405// CHECK-NEXT: 23a00c: c0 03 5f d6 ret
406 .section .text.21, "ax", %progbits406 .section .text.21, "ax", %progbits
407 .balign 4096407 .balign 4096
408 .globl t4_ffc_stpsimd408 .globl t4_ffc_stpsimd
...@@ -415,14 +415,14 @@ t4_ffc_stpsimd:...@@ -415,14 +415,14 @@ t4_ffc_stpsimd:
415 ldr x14, [x16, #8]415 ldr x14, [x16, #8]
416 ret416 ret
417417
418// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4BFFC in unpatched output.418// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23BFFC in unpatched output.
419// CHECK: t4_ffc_stnp:419// CHECK: t4_ffc_stnp:
420// CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016420// CHECK-NEXT: 23bffc: a7 00 00 b0 adrp x7, #86016
421// CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3]421// CHECK-NEXT: 23c000: 61 08 00 a8 stnp x1, x2, [x3]
422// CHECK-NEXT: 4c004: 1f 20 03 d5 nop422// CHECK-NEXT: 23c004: 1f 20 03 d5 nop
423// CHECK-FIX: 4c008: 2b 20 00 14 b #32940423// CHECK-FIX: 23c008: 2b 20 00 14 b #32940
424// CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7]424// CHECK-NOFIX: 23c008: ea 00 40 f9 ldr x10, [x7]
425// CHECK-NEXT: 4c00c: c0 03 5f d6 ret425// CHECK-NEXT: 23c00c: c0 03 5f d6 ret
426 .section .text.22, "ax", %progbits426 .section .text.22, "ax", %progbits
427 .balign 4096427 .balign 4096
428 .globl t4_ffc_stnp428 .globl t4_ffc_stnp
...@@ -435,14 +435,14 @@ t4_ffc_stnp:...@@ -435,14 +435,14 @@ t4_ffc_stnp:
435 ldr x10, [x7, :got_lo12:dat1]435 ldr x10, [x7, :got_lo12:dat1]
436 ret436 ret
437437
438// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output.438// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23DFFC in unpatched output.
439// CHECK: t4_ffc_st1:439// CHECK: t4_ffc_st1:
440// CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824440// CHECK-NEXT: 23dffc: 98 00 00 f0 adrp x24, #77824
441// CHECK-NEXT: 4e000: 20 80 00 4d st1 { v0.s }[2], [x1]441// CHECK-NEXT: 23e000: 20 80 00 4d st1 { v0.s }[2], [x1]
442// CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8]442// CHECK-NEXT: 23e004: f6 06 40 f9 ldr x22, [x23, #8]
443// CHECK-FIX: 4e008: 2d 18 00 14 b #24756443// CHECK-FIX: 23e008: 2d 18 00 14 b #24756
444// CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760]444// CHECK-NOFIX: 23e008: 18 ff 3f f9 str x24, [x24, #32760]
445// CHECK-NEXT: 4e00c: c0 03 5f d6 ret445// CHECK-NEXT: 23e00c: c0 03 5f d6 ret
446 .section .text.23, "ax", %progbits446 .section .text.23, "ax", %progbits
447 .balign 4096447 .balign 4096
448 .globl t4_ffc_st1448 .globl t4_ffc_st1
...@@ -455,14 +455,14 @@ t4_ffc_st1:...@@ -455,14 +455,14 @@ t4_ffc_st1:
455 str x24, [x24, #32760]455 str x24, [x24, #32760]
456 ret456 ret
457457
458// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4FFF8 in unpatched output.458// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FFF8 in unpatched output.
459// CHECK: t3_ff8_ldr_once:459// CHECK: t3_ff8_ldr_once:
460// CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632460// CHECK-NEXT: 23fff8: 80 00 00 b0 adrp x0, #69632
461// CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2461// CHECK-NEXT: 23fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2
462// CHECK-FIX: 50000: 31 10 00 14 b #16580462// CHECK-FIX: 240000: 31 10 00 14 b #16580
463// CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16]463// CHECK-NOFIX: 240000: 01 08 40 f9 ldr x1, [x0, #16]
464// CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16]464// CHECK-NEXT: 240004: 02 08 40 f9 ldr x2, [x0, #16]
465// CHECK-NEXT: 50008: c0 03 5f d6 ret465// CHECK-NEXT: 240008: c0 03 5f d6 ret
466 .section .text.24, "ax", %progbits466 .section .text.24, "ax", %progbits
467 .balign 4096467 .balign 4096
468 .globl t3_ff8_ldr_once468 .globl t3_ff8_ldr_once
...@@ -475,14 +475,14 @@ t3_ff8_ldr_once:...@@ -475,14 +475,14 @@ t3_ff8_ldr_once:
475 ldr x2, [x0, #16]475 ldr x2, [x0, #16]
476 ret476 ret
477477
478// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 51FF8 in unpatched output.478// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 241FF8 in unpatched output.
479// CHECK: t3_ff8_ldxr:479// CHECK: t3_ff8_ldxr:
480// CHECK-NEXT: 51ff8: 60 00 00 f0 adrp x0, #61440480// CHECK-NEXT: 241ff8: 60 00 00 f0 adrp x0, #61440
481// CHECK-NEXT: 51ffc: 03 7c 5f c8 ldxr x3, [x0]481// CHECK-NEXT: 241ffc: 03 7c 5f c8 ldxr x3, [x0]
482// CHECK-FIX: 52000: 33 08 00 14 b #8396482// CHECK-FIX: 242000: 33 08 00 14 b #8396
483// CHECK-NOFIX: 52000: 01 08 40 f9 ldr x1, [x0, #16]483// CHECK-NOFIX: 242000: 01 08 40 f9 ldr x1, [x0, #16]
484// CHECK: 52004: 02 08 40 f9 ldr x2, [x0, #16]484// CHECK: 242004: 02 08 40 f9 ldr x2, [x0, #16]
485// CHECK-NEXT: 52008: c0 03 5f d6 ret485// CHECK-NEXT: 242008: c0 03 5f d6 ret
486 .section .text.25, "ax", %progbits486 .section .text.25, "ax", %progbits
487 .balign 4096487 .balign 4096
488 .globl t3_ff8_ldxr488 .globl t3_ff8_ldxr
...@@ -495,14 +495,14 @@ t3_ff8_ldxr:...@@ -495,14 +495,14 @@ t3_ff8_ldxr:
495 ldr x2, [x0, #16]495 ldr x2, [x0, #16]
496 ret496 ret
497497
498// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 53FF8 in unpatched output.498// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 243FF8 in unpatched output.
499// CHECK: t3_ff8_stxr:499// CHECK: t3_ff8_stxr:
500// CHECK-NEXT: 53ff8: 60 00 00 b0 adrp x0, #53248500// CHECK-NEXT: 243ff8: 60 00 00 b0 adrp x0, #53248
501// CHECK-NEXT: 53ffc: 03 7c 04 c8 stxr w4, x3, [x0]501// CHECK-NEXT: 243ffc: 03 7c 04 c8 stxr w4, x3, [x0]
502// CHECK-FIX: 54000: 35 00 00 14 b #212502// CHECK-FIX: 244000: 35 00 00 14 b #212
503// CHECK-NOFIX: 54000: 01 08 40 f9 ldr x1, [x0, #16]503// CHECK-NOFIX: 244000: 01 08 40 f9 ldr x1, [x0, #16]
504// CHECK: 54004: 02 08 40 f9 ldr x2, [x0, #16]504// CHECK: 244004: 02 08 40 f9 ldr x2, [x0, #16]
505// CHECK-NEXT: 54008: c0 03 5f d6 ret505// CHECK-NEXT: 244008: c0 03 5f d6 ret
506 .section .text.26, "ax", %progbits506 .section .text.26, "ax", %progbits
507 .balign 4096507 .balign 4096
508 .globl t3_ff8_stxr508 .globl t3_ff8_stxr
...@@ -521,84 +521,84 @@ t3_ff8_stxr:...@@ -521,84 +521,84 @@ t3_ff8_stxr:
521_start:521_start:
522 ret522 ret
523523
524// CHECK-FIX: __CortexA53843419_22000:524// CHECK-FIX: __CortexA53843419_212000:
525// CHECK-FIX-NEXT: 5400c: 00 00 40 f9 ldr x0, [x0]525// CHECK-FIX-NEXT: 24400c: 00 00 40 f9 ldr x0, [x0]
526// CHECK-FIX-NEXT: 54010: fd 37 ff 17 b #-204812526// CHECK-FIX-NEXT: 244010: fd 37 ff 17 b #-204812
527// CHECK-FIX: __CortexA53843419_24000:527// CHECK-FIX: __CortexA53843419_214000:
528// CHECK-FIX-NEXT: 54014: 02 04 40 f9 ldr x2, [x0, #8]528// CHECK-FIX-NEXT: 244014: 02 04 40 f9 ldr x2, [x0, #8]
529// CHECK-FIX-NEXT: 54018: fb 3f ff 17 b #-196628529// CHECK-FIX-NEXT: 244018: fb 3f ff 17 b #-196628
530// CHECK-FIX: __CortexA53843419_26004:530// CHECK-FIX: __CortexA53843419_216004:
531// CHECK-FIX-NEXT: 5401c: 03 08 40 f9 ldr x3, [x0, #16]531// CHECK-FIX-NEXT: 24401c: 03 08 40 f9 ldr x3, [x0, #16]
532// CHECK-FIX-NEXT: 54020: fa 47 ff 17 b #-188440532// CHECK-FIX-NEXT: 244020: fa 47 ff 17 b #-188440
533// CHECK-FIX: __CortexA53843419_28000:533// CHECK-FIX: __CortexA53843419_218000:
534// CHECK-FIX-NEXT: 54024: 02 00 40 f9 ldr x2, [x0]534// CHECK-FIX-NEXT: 244024: 02 00 40 f9 ldr x2, [x0]
535// CHECK-FIX-NEXT: 54028: f7 4f ff 17 b #-180260535// CHECK-FIX-NEXT: 244028: f7 4f ff 17 b #-180260
536// CHECK-FIX: __CortexA53843419_2A004:536// CHECK-FIX: __CortexA53843419_21A004:
537// CHECK-FIX-NEXT: 5402c: 9c 07 00 f9 str x28, [x28, #8]537// CHECK-FIX-NEXT: 24402c: 9c 07 00 f9 str x28, [x28, #8]
538// CHECK-FIX-NEXT: 54030: f6 57 ff 17 b #-172072538// CHECK-FIX-NEXT: 244030: f6 57 ff 17 b #-172072
539// CHECK-FIX: __CortexA53843419_2C004:539// CHECK-FIX: __CortexA53843419_21C004:
540// CHECK-FIX-NEXT: 54034: 84 0b 00 f9 str x4, [x28, #16]540// CHECK-FIX-NEXT: 244034: 84 0b 00 f9 str x4, [x28, #16]
541// CHECK-FIX-NEXT: 54038: f4 5f ff 17 b #-163888541// CHECK-FIX-NEXT: 244038: f4 5f ff 17 b #-163888
542// CHECK-FIX: __CortexA53843419_2E000:542// CHECK-FIX: __CortexA53843419_21E000:
543// CHECK-FIX-NEXT: 5403c: bd 03 40 f9 ldr x29, [x29]543// CHECK-FIX-NEXT: 24403c: bd 03 40 f9 ldr x29, [x29]
544// CHECK-FIX-NEXT: 54040: f1 67 ff 17 b #-155708544// CHECK-FIX-NEXT: 244040: f1 67 ff 17 b #-155708
545// CHECK-FIX: __CortexA53843419_30004:545// CHECK-FIX: __CortexA53843419_220004:
546// CHECK-FIX-NEXT: 54044: bd 07 40 f9 ldr x29, [x29, #8]546// CHECK-FIX-NEXT: 244044: bd 07 40 f9 ldr x29, [x29, #8]
547// CHECK-FIX-NEXT: 54048: f0 6f ff 17 b #-147520547// CHECK-FIX-NEXT: 244048: f0 6f ff 17 b #-147520
548// CHECK-FIX: __CortexA53843419_32004:548// CHECK-FIX: __CortexA53843419_222004:
549// CHECK-FIX-NEXT: 5404c: 41 0a 40 f9 ldr x1, [x18, #16]549// CHECK-FIX-NEXT: 24404c: 41 0a 40 f9 ldr x1, [x18, #16]
550// CHECK-FIX-NEXT: 54050: ee 77 ff 17 b #-139336550// CHECK-FIX-NEXT: 244050: ee 77 ff 17 b #-139336
551// CHECK-FIX: __CortexA53843419_34000:551// CHECK-FIX: __CortexA53843419_224000:
552// CHECK-FIX-NEXT: 54054: 52 02 40 f9 ldr x18, [x18]552// CHECK-FIX-NEXT: 244054: 52 02 40 f9 ldr x18, [x18]
553// CHECK-FIX-NEXT: 54058: eb 7f ff 17 b #-131156553// CHECK-FIX-NEXT: 244058: eb 7f ff 17 b #-131156
554// CHECK-FIX: __CortexA53843419_36004:554// CHECK-FIX: __CortexA53843419_226004:
555// CHECK-FIX-NEXT: 5405c: ea 05 40 f9 ldr x10, [x15, #8]555// CHECK-FIX-NEXT: 24405c: ea 05 40 f9 ldr x10, [x15, #8]
556// CHECK-FIX-NEXT: 54060: ea 87 ff 17 b #-122968556// CHECK-FIX-NEXT: 244060: ea 87 ff 17 b #-122968
557// CHECK-FIX: __CortexA53843419_38000:557// CHECK-FIX: __CortexA53843419_228000:
558// CHECK-FIX-NEXT: 54064: 0d 0a 40 f9 ldr x13, [x16, #16]558// CHECK-FIX-NEXT: 244064: 0d 0a 40 f9 ldr x13, [x16, #16]
559// CHECK-FIX-NEXT: 54068: e7 8f ff 17 b #-114788559// CHECK-FIX-NEXT: 244068: e7 8f ff 17 b #-114788
560// CHECK-FIX: __CortexA53843419_3A004:560// CHECK-FIX: __CortexA53843419_22A004:
561// CHECK-FIX-NEXT: 5406c: e9 00 40 f9 ldr x9, [x7]561// CHECK-FIX-NEXT: 24406c: e9 00 40 f9 ldr x9, [x7]
562// CHECK-FIX-NEXT: 54070: e6 97 ff 17 b #-106600562// CHECK-FIX-NEXT: 244070: e6 97 ff 17 b #-106600
563// CHECK-FIX: __CortexA53843419_3C004:563// CHECK-FIX: __CortexA53843419_22C004:
564// CHECK-FIX-NEXT: 54074: f6 06 40 f9 ldr x22, [x23, #8]564// CHECK-FIX-NEXT: 244074: f6 06 40 f9 ldr x22, [x23, #8]
565// CHECK-FIX-NEXT: 54078: e4 9f ff 17 b #-98416565// CHECK-FIX-NEXT: 244078: e4 9f ff 17 b #-98416
566// CHECK-FIX: __CortexA53843419_3E000:566// CHECK-FIX: __CortexA53843419_22E000:
567// CHECK-FIX-NEXT: 5407c: f8 0a 40 f9 ldr x24, [x23, #16]567// CHECK-FIX-NEXT: 24407c: f8 0a 40 f9 ldr x24, [x23, #16]
568// CHECK-FIX-NEXT: 54080: e1 a7 ff 17 b #-90236568// CHECK-FIX-NEXT: 244080: e1 a7 ff 17 b #-90236
569// CHECK-FIX: __CortexA53843419_40004:569// CHECK-FIX: __CortexA53843419_230004:
570// CHECK-FIX-NEXT: 54084: 02 00 40 f9 ldr x2, [x0]570// CHECK-FIX-NEXT: 244084: 02 00 40 f9 ldr x2, [x0]
571// CHECK-FIX-NEXT: 54088: e0 af ff 17 b #-82048571// CHECK-FIX-NEXT: 244088: e0 af ff 17 b #-82048
572// CHECK-FIX: __CortexA53843419_42008:572// CHECK-FIX: __CortexA53843419_232008:
573// CHECK-FIX-NEXT: 5408c: 9b 07 00 f9 str x27, [x28, #8]573// CHECK-FIX-NEXT: 24408c: 9b 07 00 f9 str x27, [x28, #8]
574// CHECK-FIX-NEXT: 54090: df b7 ff 17 b #-73860574// CHECK-FIX-NEXT: 244090: df b7 ff 17 b #-73860
575// CHECK-FIX: __CortexA53843419_44004:575// CHECK-FIX: __CortexA53843419_234004:
576// CHECK-FIX-NEXT: 54094: 0e 0a 40 f9 ldr x14, [x16, #16]576// CHECK-FIX-NEXT: 244094: 0e 0a 40 f9 ldr x14, [x16, #16]
577// CHECK-FIX-NEXT: 54098: dc bf ff 17 b #-65680577// CHECK-FIX-NEXT: 244098: dc bf ff 17 b #-65680
578// CHECK-FIX: __CortexA53843419_46004:578// CHECK-FIX: __CortexA53843419_236004:
579// CHECK-FIX-NEXT: 5409c: 0e 06 40 f9 ldr x14, [x16, #8]579// CHECK-FIX-NEXT: 24409c: 0e 06 40 f9 ldr x14, [x16, #8]
580// CHECK-FIX-NEXT: 540a0: da c7 ff 17 b #-57496580// CHECK-FIX-NEXT: 2440a0: da c7 ff 17 b #-57496
581// CHECK-FIX: __CortexA53843419_48004:581// CHECK-FIX: __CortexA53843419_238004:
582// CHECK-FIX-NEXT: 540a4: 0e 06 40 f9 ldr x14, [x16, #8]582// CHECK-FIX-NEXT: 2440a4: 0e 06 40 f9 ldr x14, [x16, #8]
583// CHECK-FIX-NEXT: 540a8: d8 cf ff 17 b #-49312583// CHECK-FIX-NEXT: 2440a8: d8 cf ff 17 b #-49312
584// CHECK-FIX: __CortexA53843419_4A008:584// CHECK-FIX: __CortexA53843419_23A008:
585// CHECK-FIX-NEXT: 540ac: 0e 06 40 f9 ldr x14, [x16, #8]585// CHECK-FIX-NEXT: 2440ac: 0e 06 40 f9 ldr x14, [x16, #8]
586// CHECK-FIX-NEXT: 540b0: d7 d7 ff 17 b #-41124586// CHECK-FIX-NEXT: 2440b0: d7 d7 ff 17 b #-41124
587// CHECK-FIX: __CortexA53843419_4C008:587// CHECK-FIX: __CortexA53843419_23C008:
588// CHECK-FIX-NEXT: 540b4: ea 00 40 f9 ldr x10, [x7]588// CHECK-FIX-NEXT: 2440b4: ea 00 40 f9 ldr x10, [x7]
589// CHECK-FIX-NEXT: 540b8: d5 df ff 17 b #-32940589// CHECK-FIX-NEXT: 2440b8: d5 df ff 17 b #-32940
590// CHECK-FIX: __CortexA53843419_4E008:590// CHECK-FIX: __CortexA53843419_23E008:
591// CHECK-FIX-NEXT: 540bc: 18 ff 3f f9 str x24, [x24, #32760]591// CHECK-FIX-NEXT: 2440bc: 18 ff 3f f9 str x24, [x24, #32760]
592// CHECK-FIX-NEXT: 540c0: d3 e7 ff 17 b #-24756592// CHECK-FIX-NEXT: 2440c0: d3 e7 ff 17 b #-24756
593// CHECK-FIX: __CortexA53843419_50000:593// CHECK-FIX: __CortexA53843419_240000:
594// CHECK-FIX-NEXT: 540c4: 01 08 40 f9 ldr x1, [x0, #16]594// CHECK-FIX-NEXT: 2440c4: 01 08 40 f9 ldr x1, [x0, #16]
595// CHECK-FIX-NEXT: 540c8: cf ef ff 17 b #-16580595// CHECK-FIX-NEXT: 2440c8: cf ef ff 17 b #-16580
596// CHECK-FIX: __CortexA53843419_52000:596// CHECK-FIX: __CortexA53843419_242000:
597// CHECK-FIX-NEXT: 540cc: 01 08 40 f9 ldr x1, [x0, #16]597// CHECK-FIX-NEXT: 2440cc: 01 08 40 f9 ldr x1, [x0, #16]
598// CHECK-FIX-NEXT: 540d0: cd f7 ff 17 b #-8396598// CHECK-FIX-NEXT: 2440d0: cd f7 ff 17 b #-8396
599// CHECK-FIX: __CortexA53843419_54000:599// CHECK-FIX: __CortexA53843419_244000:
600// CHECK-FIX-NEXT: 540d4: 01 08 40 f9 ldr x1, [x0, #16]600// CHECK-FIX-NEXT: 2440d4: 01 08 40 f9 ldr x1, [x0, #16]
601// CHECK-FIX-NEXT: 540d8: cb ff ff 17 b #-212601// CHECK-FIX-NEXT: 2440d8: cb ff ff 17 b #-212
602 .data602 .data
603 .globl dat603 .globl dat
604 .globl dat2604 .globl dat2
deps/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s created+38
...@@ -0,0 +1,38 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
3// RUN: ld.lld -fix-cortex-a53-843419 %t.o -o %t2
4// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s
5
6// The following code sequence is covered by the TLS IE to LE relaxation. It
7// transforms the ADRP, LDR to MOVZ, MOVK. The former can trigger a
8// cortex-a53-843419 patch, whereas the latter can not. As both
9// relaxation and patching transform instructions very late in the
10// link there is a possibility of them both being simultaneously
11// applied. In this case the relaxed sequence is immune from the erratum so we
12// prefer to keep it.
13 .text
14 .balign 4096
15 .space 4096 - 8
16 .globl _start
17 .type _start,@function
18_start:
19 mrs x1, tpidr_el0
20 adrp x0, :gottprel:v
21 ldr x1, [x0, #:gottprel_lo12:v]
22 adrp x0, :gottprel:v
23 ldr x1, [x0, #:gottprel_lo12:v]
24 ret
25
26// CHECK: _start:
27// CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0
28// CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16
29// CHECK-NEXT: 211000: 01 08 80 f2 movk x1, #64
30// CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16
31// CHECK-NEXT: 211008: 01 08 80 f2 movk x1, #64
32// CHECK-NEXT: 21100c: c0 03 5f d6 ret
33
34 .type v,@object
35 .section .tbss,"awT",@nobits
36 .globl v
37v:
38 .word 0
deps/lld/test/ELF/aarch64-data-relocs.s+2-2
...@@ -12,7 +12,7 @@ _start:...@@ -12,7 +12,7 @@ _start:
12// S = 0x100, A = 0x2412// S = 0x100, A = 0x24
13// S + A = 0x12413// S + A = 0x124
14// CHECK: Contents of section .R_AARCH64_ABS64:14// CHECK: Contents of section .R_AARCH64_ABS64:
15// CHECK-NEXT: 20000 24010000 0000000015// CHECK-NEXT: 210000 24010000 00000000
1616
17.section .R_AARCH64_PREL64, "ax",@progbits17.section .R_AARCH64_PREL64, "ax",@progbits
18 .xword foo - . + 0x2418 .xword foo - . + 0x24
...@@ -20,4 +20,4 @@ _start:...@@ -20,4 +20,4 @@ _start:
20// S = 0x100, A = 0x24, P = 0x2000820// S = 0x100, A = 0x24, P = 0x20008
21// S + A - P = 0xfffffffffffe011c21// S + A - P = 0xfffffffffffe011c
22// CHECK: Contents of section .R_AARCH64_PREL64:22// CHECK: Contents of section .R_AARCH64_PREL64:
23// CHECK-NEXT: 20008 1c01feff ffffffff23// CHECK-NEXT: 210008 1c01dfff ffffffff
deps/lld/test/ELF/aarch64-gnu-ifunc-address-pie.s created+44
...@@ -0,0 +1,44 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3# RUN: ld.lld -pie %t.o -o %tout
4# RUN: llvm-objdump -D %tout | FileCheck %s
5# RUN: llvm-readobj -r %tout | FileCheck %s -check-prefix=CHECK-RELOCS
6
7# Test that when we take the address of a preemptible ifunc using -fpie, we can
8# handle the case when the ifunc is in the same translation unit as the address
9# taker. In this case the compiler knows that ifunc is not defined in a shared
10# library so it can use a non got generating relative reference.
11.text
12.globl myfunc
13.type myfunc,@gnu_indirect_function
14myfunc:
15 ret
16
17.text
18.globl main
19.type main,@function
20main:
21 adrp x8, myfunc
22 add x8, x8, :lo12: myfunc
23 ret
24
25# CHECK: 0000000000010000 myfunc:
26# CHECK-NEXT: 10000: c0 03 5f d6 ret
27# CHECK: 0000000000010004 main:
28# CHECK-NEXT: 10004: 08 00 00 90 adrp x8, #0
29# x8 = 0x10000
30# CHECK-NEXT: 10008: 08 41 00 91 add x8, x8, #16
31# x8 = 0x10010 = .plt for myfunc
32# CHECK-NEXT: 1000c: c0 03 5f d6 ret
33# CHECK-NEXT: Disassembly of section .plt:
34# CHECK-NEXT: 0000000000010010 .plt:
35# CHECK-NEXT: 10010: 90 00 00 90 adrp x16, #65536
36# CHECK-NEXT: 10014: 11 02 40 f9 ldr x17, [x16]
37# CHECK-NEXT: 10018: 10 02 00 91 add x16, x16, #0
38# CHECK-NEXT: 1001c: 20 02 1f d6 br x17
39
40# CHECK-RELOCS: Relocations [
41# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt {
42# CHECK-RELOCS-NEXT: 0x20000 R_AARCH64_IRELATIVE - 0x10000
43# CHECK-RELOCS-NEXT: }
44# CHECK-RELOCS-NEXT: ]
deps/lld/test/ELF/aarch64-gnu-ifunc-address.s created+40
...@@ -0,0 +1,40 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %tout
4# RUN: llvm-objdump -D %tout | FileCheck %s
5# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=CHECK-RELOCS
6
7# Test that when we take the address of a preemptible ifunc in a shared object
8# we get R_AARCH64_GLOB_DAT to the symbol as it could be defined in another
9# link unit and preempt our definition.
10.text
11.globl myfunc
12.type myfunc,@gnu_indirect_function
13myfunc:
14 ret
15
16.text
17.globl main
18.type main,@function
19main:
20 adrp x8, :got:myfunc
21 ldr x8, [x8, :got_lo12:myfunc]
22 ret
23# CHECK: 0000000000010004 main:
24# x8 = 0x30000
25# CHECK-NEXT: 10004: 08 01 00 90 adrp x8, #131072
26# x8 = 0x300e0 = .got entry for myfunc with R_AARCH64_GLOB_DAT
27# CHECK-NEXT: 10008: 08 71 40 f9 ldr x8, [x8, #224]
28# CHECK-NEXT: 1000c: c0 03 5f d6 ret
29
30# CHECK: Disassembly of section .got:
31# CHECK-NEXT: 00000000000300e0 .got:
32
33# CHECK-RELOCS: Relocations [
34# CHECK-RELOCS-NEXT: Section {{.*}} .rela.dyn {
35# CHECK-RELOCS-NEXT: 0x300E0 R_AARCH64_GLOB_DAT myfunc 0x0
36# CHECK-RELOCS-NEXT: }
37# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt {
38# CHECK-RELOCS-NEXT: 0x20018 R_AARCH64_JUMP_SLOT myfunc 0x0
39# CHECK-RELOCS-NEXT: }
40# CHECK-RELOCS-NEXT: ]
deps/lld/test/ELF/aarch64-gnu-ifunc-plt.s+42-38
...@@ -10,19 +10,19 @@...@@ -10,19 +10,19 @@
10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
11// CHECK: Relocations [11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rela.plt {12// CHECK-NEXT: Section (4) .rela.plt {
13// CHECK: 0x30018 R_AARCH64_JUMP_SLOT bar2 0x013// CHECK: 0x220018 R_AARCH64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT zed2 0x014// CHECK-NEXT: 0x220020 R_AARCH64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x2000015// CHECK-NEXT: 0x220028 R_AARCH64_IRELATIVE - 0x210000
16// CHECK-NEXT: 0x30030 R_AARCH64_IRELATIVE - 0x2000416// CHECK-NEXT: 0x220030 R_AARCH64_IRELATIVE - 0x210004
17// CHECK-NEXT: }17// CHECK-NEXT: }
18// CHECK-NEXT: ]18// CHECK-NEXT: ]
1919
20// Check that .got.plt entries point back to PLT header20// Check that .got.plt entries point back to PLT header
21// GOTPLT: Contents of section .got.plt:21// GOTPLT: Contents of section .got.plt:
22// GOTPLT-NEXT: 30000 00000000 00000000 00000000 0000000022// GOTPLT-NEXT: 220000 00000000 00000000 00000000 00000000
23// GOTPLT-NEXT: 30010 00000000 00000000 20000200 0000000023// GOTPLT-NEXT: 220010 00000000 00000000 20002100 00000000
24// GOTPLT-NEXT: 30020 20000200 00000000 20000200 0000000024// GOTPLT-NEXT: 220020 20002100 00000000 20002100 00000000
25// GOTPLT-NEXT: 30030 20000200 0000000025// GOTPLT-NEXT: 220030 20002100 00000000
2626
27// Check that the PLTRELSZ tag includes the IRELATIVE relocations27// Check that the PLTRELSZ tag includes the IRELATIVE relocations
28// CHECK: DynamicSection [28// CHECK: DynamicSection [
...@@ -31,40 +31,44 @@...@@ -31,40 +31,44 @@
31// Check that a PLT header is written and the ifunc entries appear last31// Check that a PLT header is written and the ifunc entries appear last
32// DISASM: Disassembly of section .text:32// DISASM: Disassembly of section .text:
33// DISASM-NEXT: foo:33// DISASM-NEXT: foo:
34// DISASM-NEXT: 20000: {{.*}} ret34// DISASM-NEXT: 210000: {{.*}} ret
35// DISASM: bar:35// DISASM: bar:
36// DISASM-NEXT: 20004: {{.*}} ret36// DISASM-NEXT: 210004: {{.*}} ret
37// DISASM: _start:37// DISASM: _start:
38// DISASM-NEXT: 20008: {{.*}} bl #8838// DISASM-NEXT: 210008: {{.*}} bl #88
39// DISASM-NEXT: 2000c: {{.*}} bl #10039// DISASM-NEXT: 21000c: {{.*}} bl #100
40// DISASM-NEXT: 20010: {{.*}} bl #4840// DISASM-NEXT: 210010: {{.*}} bl #48
41// DISASM-NEXT: 20014: {{.*}} bl #6041// DISASM-NEXT: 210014: {{.*}} bl #60
42// DISASM-NEXT: Disassembly of section .plt:42// DISASM-NEXT: Disassembly of section .plt:
43// DISASM-NEXT: .plt:43// DISASM-NEXT: .plt:
44// DISASM-NEXT: 20020: {{.*}} stp x16, x30, [sp, #-16]!44// DISASM-NEXT: 210020: {{.*}} stp x16, x30, [sp, #-16]!
45// DISASM-NEXT: 20024: {{.*}} adrp x16, #6553645// DISASM-NEXT: 210024: {{.*}} adrp x16, #65536
46// DISASM-NEXT: 20028: {{.*}} ldr x17, [x16, #16]46// DISASM-NEXT: 210028: {{.*}} ldr x17, [x16, #16]
47// DISASM-NEXT: 2002c: {{.*}} add x16, x16, #1647// DISASM-NEXT: 21002c: {{.*}} add x16, x16, #16
48// DISASM-NEXT: 20030: {{.*}} br x1748// DISASM-NEXT: 210030: {{.*}} br x17
49// DISASM-NEXT: 20034: {{.*}} nop49// DISASM-NEXT: 210034: {{.*}} nop
50// DISASM-NEXT: 20038: {{.*}} nop50// DISASM-NEXT: 210038: {{.*}} nop
51// DISASM-NEXT: 2003c: {{.*}} nop51// DISASM-NEXT: 21003c: {{.*}} nop
52// DISASM-NEXT: 20040: {{.*}} adrp x16, #6553652// DISASM-EMPTY:
53// DISASM-NEXT: 20044: {{.*}} ldr x17, [x16, #24]53// DISASM-NEXT: bar2@plt:
54// DISASM-NEXT: 20048: {{.*}} add x16, x16, #2454// DISASM-NEXT: 210040: {{.*}} adrp x16, #65536
55// DISASM-NEXT: 2004c: {{.*}} br x1755// DISASM-NEXT: 210044: {{.*}} ldr x17, [x16, #24]
56// DISASM-NEXT: 20050: {{.*}} adrp x16, #6553656// DISASM-NEXT: 210048: {{.*}} add x16, x16, #24
57// DISASM-NEXT: 20054: {{.*}} ldr x17, [x16, #32]57// DISASM-NEXT: 21004c: {{.*}} br x17
58// DISASM-NEXT: 20058: {{.*}} add x16, x16, #3258// DISASM-EMPTY:
59// DISASM-NEXT: 2005c: {{.*}} br x1759// DISASM-NEXT: zed2@plt:
60// DISASM-NEXT: 20060: {{.*}} adrp x16, #6553660// DISASM-NEXT: 210050: {{.*}} adrp x16, #65536
61// DISASM-NEXT: 20064: {{.*}} ldr x17, [x16, #40]61// DISASM-NEXT: 210054: {{.*}} ldr x17, [x16, #32]
62// DISASM-NEXT: 20068: {{.*}} add x16, x16, #4062// DISASM-NEXT: 210058: {{.*}} add x16, x16, #32
63// DISASM-NEXT: 2006c: {{.*}} br x1763// DISASM-NEXT: 21005c: {{.*}} br x17
64// DISASM-NEXT: 20070: {{.*}} adrp x16, #6553664// DISASM-NEXT: 210060: {{.*}} adrp x16, #65536
65// DISASM-NEXT: 20074: {{.*}} ldr x17, [x16, #48]65// DISASM-NEXT: 210064: {{.*}} ldr x17, [x16, #40]
66// DISASM-NEXT: 20078: {{.*}} add x16, x16, #4866// DISASM-NEXT: 210068: {{.*}} add x16, x16, #40
67// DISASM-NEXT: 2007c: {{.*}} br x1767// DISASM-NEXT: 21006c: {{.*}} br x17
68// DISASM-NEXT: 210070: {{.*}} adrp x16, #65536
69// DISASM-NEXT: 210074: {{.*}} ldr x17, [x16, #48]
70// DISASM-NEXT: 210078: {{.*}} add x16, x16, #48
71// DISASM-NEXT: 21007c: {{.*}} br x17
6872
69.text73.text
70.type foo STT_GNU_IFUNC74.type foo STT_GNU_IFUNC
deps/lld/test/ELF/aarch64-gnu-ifunc.s+23-23
...@@ -16,14 +16,14 @@...@@ -16,14 +16,14 @@
16// CHECK-NEXT: Offset: 0x15816// CHECK-NEXT: Offset: 0x158
17// CHECK-NEXT: Size: 4817// CHECK-NEXT: Size: 48
18// CHECK-NEXT: Link: 018// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 019// CHECK-NEXT: Info: 4
20// CHECK-NEXT: AddressAlignment: 820// CHECK-NEXT: AddressAlignment: 8
21// CHECK-NEXT: EntrySize: 2421// CHECK-NEXT: EntrySize: 24
22// CHECK-NEXT: }22// CHECK-NEXT: }
23// CHECK: Relocations [23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rela.plt {24// CHECK-NEXT: Section ({{.*}}) .rela.plt {
25// CHECK-NEXT: 0x30000 R_AARCH64_IRELATIVE25// CHECK-NEXT: 0x220000 R_AARCH64_IRELATIVE
26// CHECK-NEXT: 0x30008 R_AARCH64_IRELATIVE26// CHECK-NEXT: 0x220008 R_AARCH64_IRELATIVE
27// CHECK-NEXT: }27// CHECK-NEXT: }
28// CHECK-NEXT: ]28// CHECK-NEXT: ]
29// CHECK: Symbols [29// CHECK: Symbols [
...@@ -38,7 +38,7 @@...@@ -38,7 +38,7 @@
38// CHECK-NEXT: }38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: $x.040// CHECK-NEXT: Name: $x.0
41// CHECK-NEXT: Value: 0x2000041// CHECK-NEXT: Value: 0x210000
42// CHECK-NEXT: Size: 042// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Local43// CHECK-NEXT: Binding: Local
44// CHECK-NEXT: Type: None44// CHECK-NEXT: Type: None
...@@ -47,7 +47,7 @@...@@ -47,7 +47,7 @@
47// CHECK-NEXT: }47// CHECK-NEXT: }
48// CHECK-NEXT: Symbol {48// CHECK-NEXT: Symbol {
49// CHECK-NEXT: Name: __rela_iplt_end49// CHECK-NEXT: Name: __rela_iplt_end
50// CHECK-NEXT: Value: 0x1018850// CHECK-NEXT: Value: 0x200188
51// CHECK-NEXT: Size: 051// CHECK-NEXT: Size: 0
52// CHECK-NEXT: Binding: Local52// CHECK-NEXT: Binding: Local
53// CHECK-NEXT: Type: None53// CHECK-NEXT: Type: None
...@@ -58,7 +58,7 @@...@@ -58,7 +58,7 @@
58// CHECK-NEXT: }58// CHECK-NEXT: }
59// CHECK-NEXT: Symbol {59// CHECK-NEXT: Symbol {
60// CHECK-NEXT: Name: __rela_iplt_start60// CHECK-NEXT: Name: __rela_iplt_start
61// CHECK-NEXT: Value: 0x1015861// CHECK-NEXT: Value: 0x200158
62// CHECK-NEXT: Size: 062// CHECK-NEXT: Size: 0
63// CHECK-NEXT: Binding: Local63// CHECK-NEXT: Binding: Local
64// CHECK-NEXT: Type: None64// CHECK-NEXT: Type: None
...@@ -69,7 +69,7 @@...@@ -69,7 +69,7 @@
69// CHECK-NEXT: }69// CHECK-NEXT: }
70// CHECK-NEXT: Symbol {70// CHECK-NEXT: Symbol {
71// CHECK-NEXT: Name: _start71// CHECK-NEXT: Name: _start
72// CHECK-NEXT: Value: 0x2000872// CHECK-NEXT: Value: 0x210008
73// CHECK-NEXT: Size: 073// CHECK-NEXT: Size: 0
74// CHECK-NEXT: Binding: Global74// CHECK-NEXT: Binding: Global
75// CHECK-NEXT: Type: None75// CHECK-NEXT: Type: None
...@@ -78,7 +78,7 @@...@@ -78,7 +78,7 @@
78// CHECK-NEXT: }78// CHECK-NEXT: }
79// CHECK-NEXT: Symbol {79// CHECK-NEXT: Symbol {
80// CHECK-NEXT: Name: bar80// CHECK-NEXT: Name: bar
81// CHECK-NEXT: Value: 0x2000481// CHECK-NEXT: Value: 0x210004
82// CHECK-NEXT: Size: 082// CHECK-NEXT: Size: 0
83// CHECK-NEXT: Binding: Global83// CHECK-NEXT: Binding: Global
84// CHECK-NEXT: Type: GNU_IFunc84// CHECK-NEXT: Type: GNU_IFunc
...@@ -87,7 +87,7 @@...@@ -87,7 +87,7 @@
87// CHECK-NEXT: }87// CHECK-NEXT: }
88// CHECK-NEXT: Symbol {88// CHECK-NEXT: Symbol {
89// CHECK-NEXT: Name: foo89// CHECK-NEXT: Name: foo
90// CHECK-NEXT: Value: 0x2000090// CHECK-NEXT: Value: 0x210000
91// CHECK-NEXT: Size: 091// CHECK-NEXT: Size: 0
92// CHECK-NEXT: Binding: Global92// CHECK-NEXT: Binding: Global
93// CHECK-NEXT: Type: GNU_IFunc93// CHECK-NEXT: Type: GNU_IFunc
...@@ -101,24 +101,24 @@...@@ -101,24 +101,24 @@
101101
102// DISASM: Disassembly of section .text:102// DISASM: Disassembly of section .text:
103// DISASM-NEXT: foo:103// DISASM-NEXT: foo:
104// DISASM-NEXT: 20000: c0 03 5f d6 ret104// DISASM-NEXT: 210000: c0 03 5f d6 ret
105// DISASM: bar:105// DISASM: bar:
106// DISASM-NEXT: 20004: c0 03 5f d6 ret106// DISASM-NEXT: 210004: c0 03 5f d6 ret
107// DISASM: _start:107// DISASM: _start:
108// DISASM-NEXT: 20008: 06 00 00 94 bl #24108// DISASM-NEXT: 210008: 06 00 00 94 bl #24
109// DISASM-NEXT: 2000c: 09 00 00 94 bl #36109// DISASM-NEXT: 21000c: 09 00 00 94 bl #36
110// DISASM-NEXT: 20010: 42 60 05 91 add x2, x2, #344110// DISASM-NEXT: 210010: 42 60 05 91 add x2, x2, #344
111// DISASM-NEXT: 20014: 42 20 06 91 add x2, x2, #392111// DISASM-NEXT: 210014: 42 20 06 91 add x2, x2, #392
112// DISASM-NEXT: Disassembly of section .plt:112// DISASM-NEXT: Disassembly of section .plt:
113// DISASM-NEXT: .plt:113// DISASM-NEXT: .plt:
114// DISASM-NEXT: 20020: 90 00 00 90 adrp x16, #65536114// DISASM-NEXT: 210020: 90 00 00 90 adrp x16, #65536
115// DISASM-NEXT: 20024: 11 02 40 f9 ldr x17, [x16]115// DISASM-NEXT: 210024: 11 02 40 f9 ldr x17, [x16]
116// DISASM-NEXT: 20028: 10 02 00 91 add x16, x16, #0116// DISASM-NEXT: 210028: 10 02 00 91 add x16, x16, #0
117// DISASM-NEXT: 2002c: 20 02 1f d6 br x17117// DISASM-NEXT: 21002c: 20 02 1f d6 br x17
118// DISASM-NEXT: 20030: 90 00 00 90 adrp x16, #65536118// DISASM-NEXT: 210030: 90 00 00 90 adrp x16, #65536
119// DISASM-NEXT: 20034: 11 06 40 f9 ldr x17, [x16, #8]119// DISASM-NEXT: 210034: 11 06 40 f9 ldr x17, [x16, #8]
120// DISASM-NEXT: 20038: 10 22 00 91 add x16, x16, #8120// DISASM-NEXT: 210038: 10 22 00 91 add x16, x16, #8
121// DISASM-NEXT: 2003c: 20 02 1f d6 br x17121// DISASM-NEXT: 21003c: 20 02 1f d6 br x17
122122
123.text123.text
124.type foo STT_GNU_IFUNC124.type foo STT_GNU_IFUNC
deps/lld/test/ELF/aarch64-gnu-ifunc2.s created+52
...@@ -0,0 +1,52 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3# RUN: ld.lld -static %t.o -o %tout
4# RUN: llvm-objdump -D %tout | FileCheck %s
5# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
6
7# CHECK: Disassembly of section .text:
8# CHECK-NEXT: myfunc:
9# CHECK-NEXT: 210000:
10
11# CHECK: main:
12# adrp x8, 0x230000, 0x230000 == address in .got
13# CHECK-NEXT: 210004: {{.*}} adrp x8, #131072
14# CHECK-NEXT: 210008: {{.*}} ldr x8, [x8]
15# CHECK-NEXT: 21000c: {{.*}} ret
16
17# CHECK: Disassembly of section .plt:
18# CHECK-NEXT: .plt:
19# adrp x16, 0x220000, 0x220000 == address in .got.plt
20# CHECK-NEXT: 210010: {{.*}} adrp x16, #65536
21# CHECK-NEXT: 210014: {{.*}} ldr x17, [x16]
22# CHECK-NEXT: 210018: {{.*}} add x16, x16, #0
23# CHECK-NEXT: 21001c: {{.*}} br x17
24
25# CHECK: Disassembly of section .got.plt:
26# CHECK-NEXT: .got.plt:
27# CHECK-NEXT: 220000:
28
29# CHECK: Disassembly of section .got:
30# CHECK-NEXT: .got:
31# 0x210010 == address in .plt
32# CHECK-NEXT: 230000: 10 00 21 00
33
34# RELOC: Relocations [
35# RELOC-NEXT: Section {{.*}} .rela.plt {
36# RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
37# RELOC-NEXT: }
38# RELOC-NEXT: ]
39
40.text
41.globl myfunc
42.type myfunc,@gnu_indirect_function
43myfunc:
44 ret
45
46.text
47.globl main
48.type main,@function
49main:
50 adrp x8, :got:myfunc
51 ldr x8, [x8, :got_lo12:myfunc]
52 ret
deps/lld/test/ELF/aarch64-gnu-ifunc3.s created+49
...@@ -0,0 +1,49 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3# RUN: ld.lld -static %t.o -o %tout
4# RUN: llvm-objdump -D %tout | FileCheck %s
5# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
6
7# The address of myfunc is the address of the PLT entry for myfunc.
8# The adrp to myfunc should generate a PLT entry and a got entry with an
9# irelative relocation.
10.text
11.globl myfunc
12.type myfunc,@gnu_indirect_function
13myfunc:
14 ret
15
16.text
17.globl _start
18.type _start,@function
19_start:
20 adrp x8, myfunc
21 add x8, x8, :lo12:myfunc
22 ret
23
24# CHECK: Disassembly of section .text:
25# CHECK-NEXT: myfunc:
26# CHECK-NEXT: 210000: c0 03 5f d6 ret
27# CHECK: _start:
28# adrp x8, 0x210000 + 0x10 from add == .plt entry
29# CHECK-NEXT: 210004: 08 00 00 90 adrp x8, #0
30# CHECK-NEXT: 210008: 08 41 00 91 add x8, x8, #16
31# CHECK-NEXT: 21000c: c0 03 5f d6 ret
32# CHECK-NEXT: Disassembly of section .plt:
33# CHECK-NEXT: .plt:
34# adrp x16, 0x220000, 0x220000 == address in .got.plt
35# CHECK-NEXT: 210010: 90 00 00 90 adrp x16, #65536
36# CHECK-NEXT: 210014: 11 02 40 f9 ldr x17, [x16]
37# CHECK-NEXT: 210018: 10 02 00 91 add x16, x16, #0
38# CHECK-NEXT: 21001c: 20 02 1f d6 br x17
39# CHECK-NEXT: Disassembly of section .got.plt:
40# CHECK-NEXT: .got.plt:
41# 0x210010 == address in .plt
42# CHECK-NEXT: 220000: 10 00 21 00
43# CHECK-NEXT: 220004: 00 00 00 00
44
45# RELOC: Relocations [
46# RELOC-NEXT: Section (1) .rela.plt {
47# RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
48# RELOC-NEXT: }
49# RELOC-NEXT: ]
deps/lld/test/ELF/aarch64-jump26-thunk.s+5-5
...@@ -11,10 +11,10 @@ _start:...@@ -11,10 +11,10 @@ _start:
1111
12// CHECK: Disassembly of section .text:12// CHECK: Disassembly of section .text:
13// CHECK-NEXT: _start:13// CHECK-NEXT: _start:
14// CHECK-NEXT: 20000: 02 00 00 14 b #814// CHECK-NEXT: 210000: 02 00 00 14 b #8
15// CHECK: __AArch64AbsLongThunk_big:15// CHECK: __AArch64AbsLongThunk_big:
16// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #816// CHECK-NEXT: 210008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 2000c: 00 02 1f d6 br x1617// CHECK-NEXT: 21000c: 00 02 1f d6 br x16
18// CHECK: $d:18// CHECK: $d:
19// CHECK-NEXT: 20010: 00 00 00 00 .word 0x0000000019// CHECK-NEXT: 210010: 00 00 00 00 .word 0x00000000
20// CHECK-NEXT: 20014: 10 00 00 00 .word 0x0000001020// CHECK-NEXT: 210014: 10 00 00 00 .word 0x00000010
deps/lld/test/ELF/aarch64-lo12-alignment.s+4-4
...@@ -39,7 +39,7 @@ foo4:...@@ -39,7 +39,7 @@ foo4:
39foo8:39foo8:
40 .space 840 .space 8
4141
42// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x30001 is not aligned to 2 bytes42// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x220001 is not aligned to 2 bytes
43// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x30002 is not aligned to 4 bytes43// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x220002 is not aligned to 4 bytes
44// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x30004 is not aligned to 8 bytes44// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x220004 is not aligned to 8 bytes
45// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x30008 is not aligned to 16 bytes45// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x220008 is not aligned to 16 bytes
deps/lld/test/ELF/aarch64-prel16.s+12-12
...@@ -7,8 +7,8 @@...@@ -7,8 +7,8 @@
7.globl _start7.globl _start
8_start:8_start:
9.data9.data
10 .hword foo - . + 0x20eff10 .hword foo - . + 0x210eff
11 .hword foo - . + 0x8f0211 .hword foo - . + 0x1f8f02
1212
13// Note: If this test fails, it probably happens because of13// Note: If this test fails, it probably happens because of
14// the change of the address of the .data section.14// the change of the address of the .data section.
...@@ -18,14 +18,14 @@ _start:...@@ -18,14 +18,14 @@ _start:
18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1919
20// CHECK: Contents of section .data:20// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x20eff, P = 0x1100021// 201000: S = 0x100, A = 0x210eff, P = 0x201000
22// S + A - P = 0xffff22// S + A - P = 0xffff
23// 11002: S = 0x100, A = 0x8f02, P = 0x1100223// 201002: S = 0x100, A = 0x1f8f02, P = 0x201002
24// S + A - P = 0x800024// S + A - P = 0x8000
25// CHECK-NEXT: 11000 ffff008025// CHECK-NEXT: 201000 ffff0080
2626
27// RUN: not ld.lld %t.o %t255.o -o %t227// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
28// | FileCheck %s --check-prefix=OVERFLOW28// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 32767]
29// RUN: not ld.lld %t.o %t257.o -o %t229
30// | FileCheck %s --check-prefix=OVERFLOW30// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
31// OVERFLOW: Relocation R_AARCH64_PREL16 out of range: -94209 is not in [-32768, 65535]31// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 32767]
deps/lld/test/ELF/aarch64-prel32.s+12-12
...@@ -7,8 +7,8 @@...@@ -7,8 +7,8 @@
7.globl _start7.globl _start
8_start:8_start:
9.data9.data
10 .word foo - . + 0x100010eff10 .word foo - . + 0x100200eff
11 .word foo - . - 0x7ffef0fc11 .word foo - . - 0x7fdff0fc
1212
13// Note: If this test fails, it probably happens because of13// Note: If this test fails, it probably happens because of
14// the change of the address of the .data section.14// the change of the address of the .data section.
...@@ -18,14 +18,14 @@ _start:...@@ -18,14 +18,14 @@ _start:
18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1919
20// CHECK: Contents of section .data:20// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x100010eff, P = 0x1100021// 201000: S = 0x100, A = 0x100200eff, P = 0x201000
22// S + A - P = 0xffffffff22// S + A - P = 0xffffffff
23// 11004: S = 0x100, A = -0x7ffef0fc, P = 0x1100423// 201004: S = 0x100, A = -0x7fdff0fc, P = 0x201004
24// S + A - P = 0x8000000024// S + A - P = 0x80000000
25// CHECK-NEXT: 11000 ffffffff 0000008025// CHECK-NEXT: 201000 ffffffff 00000080
2626
27// RUN: not ld.lld %t.o %t255.o -o %t227// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
28// | FileCheck %s --check-prefix=OVERFLOW28// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 2147483647]
29// RUN: not ld.lld %t.o %t257.o -o %t229
30// | FileCheck %s --check-prefix=OVERFLOW30// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
31// OVERFLOW: Relocation R_AARCH64_PREL32 out of range: 18446744071562006527 is not in [-2147483648, 4294967295]31// OVERFLOW2: relocation R_AARCH64_PREL32 out of range: 4294967296 is not in [-2147483648, 2147483647]
deps/lld/test/ELF/aarch64-relocs.s+25-25
...@@ -24,13 +24,13 @@ mystr:...@@ -24,13 +24,13 @@ mystr:
24 .asciz "blah"24 .asciz "blah"
25 .size mystr, 425 .size mystr, 4
2626
27# S = 0x20012, A = 0x4, P = 0x2001227# S = 0x210012, A = 0x4, P = 0x210012
28# PAGE(S + A) = 0x1100028# PAGE(S + A) = 0x210000
29# PAGE(P) = 0x1100029# PAGE(P) = 0x210000
30#30#
31# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:31# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
32# CHECK-NEXT: $x.2:32# CHECK-NEXT: $x.2:
33# CHECK-NEXT: 20012: 01 00 00 90 adrp x1, #033# CHECK-NEXT: 210012: 01 00 00 90 adrp x1, #0
3434
35.section .R_AARCH64_ADD_ABS_LO12_NC,"ax",@progbits35.section .R_AARCH64_ADD_ABS_LO12_NC,"ax",@progbits
36 add x0, x0, :lo12:.L.str36 add x0, x0, :lo12:.L.str
...@@ -38,13 +38,13 @@ mystr:...@@ -38,13 +38,13 @@ mystr:
38 .asciz "blah"38 .asciz "blah"
39 .size mystr, 439 .size mystr, 4
4040
41# S = 0x2001b, A = 0x441# S = 0x21001b, A = 0x4
42# R = (S + A) & 0xFFF = 0x1f42# R = (S + A) & 0xFFF = 0x1f
43# R << 10 = 0x7c0043# R << 10 = 0x7c00
44#44#
45# CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:45# CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:
46# CHECK-NEXT: $x.4:46# CHECK-NEXT: $x.4:
47# CHECK-NEXT: 2001b: 00 7c 00 91 add x0, x0, #3147# CHECK-NEXT: 21001b: 00 7c 00 91 add x0, x0, #31
4848
49.section .R_AARCH64_LDST64_ABS_LO12_NC,"ax",@progbits49.section .R_AARCH64_LDST64_ABS_LO12_NC,"ax",@progbits
50 ldr x28, [x27, :lo12:foo]50 ldr x28, [x27, :lo12:foo]
...@@ -52,12 +52,12 @@ foo:...@@ -52,12 +52,12 @@ foo:
52 .asciz "foo"52 .asciz "foo"
53 .size mystr, 353 .size mystr, 3
5454
55# S = 0x20024, A = 0x455# S = 0x210024, A = 0x4
56# R = ((S + A) & 0xFFF) << 7 = 0x0000140056# R = ((S + A) & 0xFFF) << 7 = 0x00001400
57# 0x00001400 | 0xf940177c = 0xf940177c57# 0x00001400 | 0xf940177c = 0xf940177c
58# CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:58# CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:
59# CHECK-NEXT: $x.6:59# CHECK-NEXT: $x.6:
60# CHECK-NEXT: 20024: 7c 17 40 f9 ldr x28, [x27, #40]60# CHECK-NEXT: 210024: 7c 17 40 f9 ldr x28, [x27, #40]
6161
62.section .SUB,"ax",@progbits62.section .SUB,"ax",@progbits
63 nop63 nop
...@@ -66,33 +66,33 @@ sub:...@@ -66,33 +66,33 @@ sub:
6666
67# CHECK: Disassembly of section .SUB:67# CHECK: Disassembly of section .SUB:
68# CHECK-NEXT: $x.8:68# CHECK-NEXT: $x.8:
69# CHECK-NEXT: 2002c: 1f 20 03 d5 nop69# CHECK-NEXT: 21002c: 1f 20 03 d5 nop
70# CHECK: sub:70# CHECK: sub:
71# CHECK-NEXT: 20030: 1f 20 03 d5 nop71# CHECK-NEXT: 210030: 1f 20 03 d5 nop
7272
73.section .R_AARCH64_CALL26,"ax",@progbits73.section .R_AARCH64_CALL26,"ax",@progbits
74call26:74call26:
75 bl sub75 bl sub
7676
77# S = 0x2002c, A = 0x4, P = 0x2003477# S = 0x21002c, A = 0x4, P = 0x210034
78# R = S + A - P = -0x4 = 0xfffffffc78# R = S + A - P = -0x4 = 0xfffffffc
79# (R & 0x0ffffffc) >> 2 = 0x03ffffff79# (R & 0x0ffffffc) >> 2 = 0x03ffffff
80# 0x94000000 | 0x03ffffff = 0x97ffffff80# 0x94000000 | 0x03ffffff = 0x97ffffff
81# CHECK: Disassembly of section .R_AARCH64_CALL26:81# CHECK: Disassembly of section .R_AARCH64_CALL26:
82# CHECK-NEXT: call26:82# CHECK-NEXT: call26:
83# CHECK-NEXT: 20034: ff ff ff 97 bl #-483# CHECK-NEXT: 210034: ff ff ff 97 bl #-4
8484
85.section .R_AARCH64_JUMP26,"ax",@progbits85.section .R_AARCH64_JUMP26,"ax",@progbits
86jump26:86jump26:
87 b sub87 b sub
8888
89# S = 0x2002c, A = 0x4, P = 0x2003889# S = 0x21002c, A = 0x4, P = 0x210038
90# R = S + A - P = -0x8 = 0xfffffff890# R = S + A - P = -0x8 = 0xfffffff8
91# (R & 0x0ffffffc) >> 2 = 0x03fffffe91# (R & 0x0ffffffc) >> 2 = 0x03fffffe
92# 0x14000000 | 0x03fffffe = 0x17fffffe92# 0x14000000 | 0x03fffffe = 0x17fffffe
93# CHECK: Disassembly of section .R_AARCH64_JUMP26:93# CHECK: Disassembly of section .R_AARCH64_JUMP26:
94# CHECK-NEXT: jump26:94# CHECK-NEXT: jump26:
95# CHECK-NEXT: 20038: fe ff ff 17 b #-895# CHECK-NEXT: 210038: fe ff ff 17 b #-8
9696
97.section .R_AARCH64_LDST32_ABS_LO12_NC,"ax",@progbits97.section .R_AARCH64_LDST32_ABS_LO12_NC,"ax",@progbits
98ldst32:98ldst32:
...@@ -101,12 +101,12 @@ foo32:...@@ -101,12 +101,12 @@ foo32:
101 .asciz "foo"101 .asciz "foo"
102 .size mystr, 3102 .size mystr, 3
103103
104# S = 0x2003c, A = 0x4104# S = 0x21003c, A = 0x4
105# R = ((S + A) & 0xFFC) << 8 = 0x00004000105# R = ((S + A) & 0xFFC) << 8 = 0x00004000
106# 0x00004000 | 0xbd4000a4 = 0xbd4040a4106# 0x00004000 | 0xbd4000a4 = 0xbd4040a4
107# CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:107# CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:
108# CHECK-NEXT: ldst32:108# CHECK-NEXT: ldst32:
109# CHECK-NEXT: 2003c: a4 40 40 bd ldr s4, [x5, #64]109# CHECK-NEXT: 21003c: a4 40 40 bd ldr s4, [x5, #64]
110110
111.section .R_AARCH64_LDST8_ABS_LO12_NC,"ax",@progbits111.section .R_AARCH64_LDST8_ABS_LO12_NC,"ax",@progbits
112ldst8:112ldst8:
...@@ -115,12 +115,12 @@ foo8:...@@ -115,12 +115,12 @@ foo8:
115 .asciz "foo"115 .asciz "foo"
116 .size mystr, 3116 .size mystr, 3
117117
118# S = 0x20044, A = 0x4118# S = 0x210044, A = 0x4
119# R = ((S + A) & 0xFFF) << 10 = 0x00012000119# R = ((S + A) & 0xFFF) << 10 = 0x00012000
120# 0x00012000 | 0x398001ab = 0x398121ab120# 0x00012000 | 0x398001ab = 0x398121ab
121# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:121# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
122# CHECK-NEXT: ldst8:122# CHECK-NEXT: ldst8:
123# CHECK-NEXT: 20044: ab 21 81 39 ldrsb x11, [x13, #72]123# CHECK-NEXT: 210044: ab 21 81 39 ldrsb x11, [x13, #72]
124124
125.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits125.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits
126ldst128:126ldst128:
...@@ -129,14 +129,14 @@ foo128:...@@ -129,14 +129,14 @@ foo128:
129 .asciz "foo"129 .asciz "foo"
130 .size mystr, 3130 .size mystr, 3
131131
132# S = 0x2004c, A = 0x4132# S = 0x21004c, A = 0x4
133# R = ((S + A) & 0xFF8) << 6 = 0x00001400133# R = ((S + A) & 0xFF8) << 6 = 0x00001400
134# 0x00001400 | 0x3dc00274 = 0x3dc01674134# 0x00001400 | 0x3dc00274 = 0x3dc01674
135# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:135# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
136# CHECK: ldst128:136# CHECK: ldst128:
137# CHECK: 2004c: 74 16 c0 3d ldr q20, [x19, #80]137# CHECK: 21004c: 74 16 c0 3d ldr q20, [x19, #80]
138#foo128:138#foo128:
139# 20050: 66 6f 6f 00 .word139# 210050: 66 6f 6f 00 .word
140140
141.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits141.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits
142ldst16:142ldst16:
...@@ -147,14 +147,14 @@ foo16:...@@ -147,14 +147,14 @@ foo16:
147 .asciz "foo"147 .asciz "foo"
148 .size mystr, 4148 .size mystr, 4
149149
150# S = 0x20054, A = 0x4150# S = 0x210054, A = 0x4
151# R = ((S + A) & 0x0FFC) << 9 = 0xb000151# R = ((S + A) & 0x0FFC) << 9 = 0xb000
152# 0xb000 | 0x7d400271 = 0x7d40b271152# 0xb000 | 0x7d400271 = 0x7d40b271
153# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:153# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
154# CHECK-NEXT: ldst16:154# CHECK-NEXT: ldst16:
155# CHECK-NEXT: 20054: 71 c2 40 7d ldr h17, [x19, #96]155# CHECK-NEXT: 210054: 71 c2 40 7d ldr h17, [x19, #96]
156# CHECK-NEXT: 20058: 61 c2 40 79 ldrh w1, [x19, #96]156# CHECK-NEXT: 210058: 61 c2 40 79 ldrh w1, [x19, #96]
157# CHECK-NEXT: 2005c: 62 c6 40 79 ldrh w2, [x19, #98]157# CHECK-NEXT: 21005c: 62 c6 40 79 ldrh w2, [x19, #98]
158158
159.section .R_AARCH64_MOVW_UABS,"ax",@progbits159.section .R_AARCH64_MOVW_UABS,"ax",@progbits
160movz1:160movz1:
deps/lld/test/ELF/aarch64-thunk-pi.s+4
...@@ -81,10 +81,14 @@ high_target2:...@@ -81,10 +81,14 @@ high_target2:
81// CHECK-NEXT: 10000034: 1f 20 03 d5 nop81// CHECK-NEXT: 10000034: 1f 20 03 d5 nop
82// CHECK-NEXT: 10000038: 1f 20 03 d5 nop82// CHECK-NEXT: 10000038: 1f 20 03 d5 nop
83// CHECK-NEXT: 1000003c: 1f 20 03 d5 nop83// CHECK-NEXT: 1000003c: 1f 20 03 d5 nop
84// CHECK-EMPTY:
85// CHECK-NEXT: high_target@plt:
84// CHECK-NEXT: 10000040: 10 00 00 90 adrp x16, #086// CHECK-NEXT: 10000040: 10 00 00 90 adrp x16, #0
85// CHECK-NEXT: 10000044: 11 3e 40 f9 ldr x17, [x16, #120]87// CHECK-NEXT: 10000044: 11 3e 40 f9 ldr x17, [x16, #120]
86// CHECK-NEXT: 10000048: 10 e2 01 91 add x16, x16, #12088// CHECK-NEXT: 10000048: 10 e2 01 91 add x16, x16, #120
87// CHECK-NEXT: 1000004c: 20 02 1f d6 br x1789// CHECK-NEXT: 1000004c: 20 02 1f d6 br x17
90// CHECK-EMPTY:
91// CHECK-NEXT: low_target@plt:
88// CHECK-NEXT: 10000050: 10 00 00 90 adrp x16, #092// CHECK-NEXT: 10000050: 10 00 00 90 adrp x16, #0
89// CHECK-NEXT: 10000054: 11 42 40 f9 ldr x17, [x16, #128]93// CHECK-NEXT: 10000054: 11 42 40 f9 ldr x17, [x16, #128]
90// CHECK-NEXT: 10000058: 10 02 02 91 add x16, x16, #12894// CHECK-NEXT: 10000058: 10 02 02 91 add x16, x16, #128
deps/lld/test/ELF/aarch64-thunk-section-location.s+4-4
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: aarch641// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t2// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-objdump -d -start-address=134086664 -stop-address=134086676 -triple=aarch64-linux-gnu %t2 | FileCheck %s4// RUN: llvm-objdump -d -start-address=136118280 -stop-address=136118292 -triple=aarch64-linux-gnu %t2 | FileCheck %s
5// Check that the range extension thunks are dumped close to the aarch64 branch5// Check that the range extension thunks are dumped close to the aarch64 branch
6// range of 128 MiB6// range of 128 MiB
7 .section .text.1, "ax", %progbits7 .section .text.1, "ax", %progbits
...@@ -35,7 +35,7 @@ high_target:...@@ -35,7 +35,7 @@ high_target:
35 ret35 ret
3636
37// CHECK: __AArch64AbsLongThunk_high_target:37// CHECK: __AArch64AbsLongThunk_high_target:
38// CHECK-NEXT: 7fe0008: 50 00 00 58 ldr x16, #838// CHECK-NEXT: 81d0008: 50 00 00 58 ldr x16, #8
39// CHECK-NEXT: 7fe000c: 00 02 1f d6 br x1639// CHECK-NEXT: 81d000c: 00 02 1f d6 br x16
40// CHECK: $d:40// CHECK: $d:
41// CHECK-NEXT: 7fe0010: 00 10 02 08 .word 0x0802100041// CHECK-NEXT: 81d0010: 00 10 21 08 .word 0x08211000
deps/lld/test/ELF/aarch64-tls-gdie.s+7-7
...@@ -21,14 +21,14 @@ _start:...@@ -21,14 +21,14 @@ _start:
21// SEC-NEXT: SHF_ALLOC21// SEC-NEXT: SHF_ALLOC
22// SEC-NEXT: SHF_WRITE22// SEC-NEXT: SHF_WRITE
23// SEC-NEXT: ]23// SEC-NEXT: ]
24// SEC-NEXT: Address: 0x300B024// SEC-NEXT: Address: 0x2200B0
2525
26// page(0x300B0) - page(0x20004) = 6553626// page(0x2200B0) - page(0x20004) = 65536
27// 0x0B0 = 17627// 0x0B0 = 176
2828
29// CHECK: _start:29// CHECK: _start:
30// CHECK-NEXT: 20000: {{.*}} nop30// CHECK-NEXT: 210000: {{.*}} nop
31// CHECK-NEXT: 20004: {{.*}} adrp x0, #6553631// CHECK-NEXT: 210004: {{.*}} adrp x0, #65536
32// CHECK-NEXT: 20008: {{.*}} ldr x0, [x0, #176]32// CHECK-NEXT: 210008: {{.*}} ldr x0, [x0, #176]
33// CHECK-NEXT: 2000c: {{.*}} nop33// CHECK-NEXT: 21000c: {{.*}} nop
34// CHECK-NEXT: 20010: {{.*}} nop34// CHECK-NEXT: 210010: {{.*}} nop
deps/lld/test/ELF/aarch64-tls-gdle.s+6-6
...@@ -5,17 +5,17 @@...@@ -5,17 +5,17 @@
5# RUN: llvm-objdump -d %tout | FileCheck %s5# RUN: llvm-objdump -d %tout | FileCheck %s
6# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s6# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
77
8#Local-Dynamic to Initial-Exec relax creates no8#Local-Dynamic to Local-Exec relax creates no
9#RELOC: Relocations [9#RELOC: Relocations [
10#RELOC-NEXT: ]10#RELOC-NEXT: ]
1111
12# TCB size = 0x16 and foo is first element from TLS register.12# TCB size = 64 and foo is first element from TLS register.
13# CHECK: Disassembly of section .text:13# CHECK: Disassembly of section .text:
14# CHECK: _start:14# CHECK: _start:
15# CHECK: 20000: 00 00 a0 d2 movz x0, #0, lsl #1615# CHECK: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK: 20004: 00 02 80 f2 movk x0, #1616# CHECK: 210004: 00 08 80 f2 movk x0, #64
17# CHECK: 20008: 1f 20 03 d5 nop17# CHECK: 210008: 1f 20 03 d5 nop
18# CHECK: 2000c: 1f 20 03 d5 nop18# CHECK: 21000c: 1f 20 03 d5 nop
1919
20.globl _start20.globl _start
21_start:21_start:
deps/lld/test/ELF/aarch64-tls-ie.s+11-11
...@@ -15,7 +15,7 @@...@@ -15,7 +15,7 @@
15#RELOC-NEXT: SHF_ALLOC15#RELOC-NEXT: SHF_ALLOC
16#RELOC-NEXT: SHF_WRITE16#RELOC-NEXT: SHF_WRITE
17#RELOC-NEXT: ]17#RELOC-NEXT: ]
18#RELOC-NEXT: Address: 0x300B018#RELOC-NEXT: Address: 0x2200B0
19#RELOC-NEXT: Offset: 0x200B019#RELOC-NEXT: Offset: 0x200B0
20#RELOC-NEXT: Size: 1620#RELOC-NEXT: Size: 16
21#RELOC-NEXT: Link: 021#RELOC-NEXT: Link: 0
...@@ -25,21 +25,21 @@...@@ -25,21 +25,21 @@
25#RELOC-NEXT: }25#RELOC-NEXT: }
26#RELOC: Relocations [26#RELOC: Relocations [
27#RELOC-NEXT: Section ({{.*}}) .rela.dyn {27#RELOC-NEXT: Section ({{.*}}) .rela.dyn {
28#RELOC-NEXT: 0x300B8 R_AARCH64_TLS_TPREL64 bar 0x028#RELOC-NEXT: 0x2200B8 R_AARCH64_TLS_TPREL64 bar 0x0
29#RELOC-NEXT: 0x300B0 R_AARCH64_TLS_TPREL64 foo 0x029#RELOC-NEXT: 0x2200B0 R_AARCH64_TLS_TPREL64 foo 0x0
30#RELOC-NEXT: }30#RELOC-NEXT: }
31#RELOC-NEXT:]31#RELOC-NEXT:]
3232
33# Page(0x300B0) - Page(0x20000) = 0x10000 = 6553633# Page(0x2200B0) - Page(0x210000) = 0x10000 = 65536
34# 0x300B0 & 0xff8 = 0xB0 = 17634# 0x2200B0 & 0xff8 = 0xB0 = 176
35# Page(0x300B8) - Page(0x20000) = 0x10000 = 6553635# Page(0x2200B8) - Page(0x210000) = 0x10000 = 65536
36# 0x300B8 & 0xff8 = 0xB8 = 18436# 0x2200B8 & 0xff8 = 0xB8 = 184
37#CHECK: Disassembly of section .text:37#CHECK: Disassembly of section .text:
38#CHECK: _start:38#CHECK: _start:
39#CHECK: 20000: 80 00 00 90 adrp x0, #6553639#CHECK: 210000: 80 00 00 90 adrp x0, #65536
40#CHECK: 20004: 00 58 40 f9 ldr x0, [x0, #176]40#CHECK: 210004: 00 58 40 f9 ldr x0, [x0, #176]
41#CHECK: 20008: 80 00 00 90 adrp x0, #6553641#CHECK: 210008: 80 00 00 90 adrp x0, #65536
42#CHECK: 2000c: 00 5c 40 f9 ldr x0, [x0, #184]42#CHECK: 21000c: 00 5c 40 f9 ldr x0, [x0, #184]
4343
44.globl _start44.globl _start
45_start:45_start:
deps/lld/test/ELF/aarch64-tls-iele.s+5-5
...@@ -9,13 +9,13 @@...@@ -9,13 +9,13 @@
9# RELOC: Relocations [9# RELOC: Relocations [
10# RELOC-NEXT: ]10# RELOC-NEXT: ]
1111
12# TCB size = 0x16 and foo is first element from TLS register.12# TCB size = 64 and foo is first element from TLS register.
13# CHECK: Disassembly of section .text:13# CHECK: Disassembly of section .text:
14# CHECK: _start:14# CHECK: _start:
15# CHECK-NEXT: 20000: 00 00 a0 d2 movz x0, #0, lsl #1615# CHECK-NEXT: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK-NEXT: 20004: 80 02 80 f2 movk x0, #2016# CHECK-NEXT: 210004: 80 08 80 f2 movk x0, #68
17# CHECK-NEXT: 20008: 00 00 a0 d2 movz x0, #0, lsl #1617# CHECK-NEXT: 210008: 00 00 a0 d2 movz x0, #0, lsl #16
18# CHECK-NEXT: 2000c: 00 02 80 f2 movk x0, #1618# CHECK-NEXT: 21000c: 00 08 80 f2 movk x0, #64
1919
20.section .tdata20.section .tdata
21.align 221.align 2
deps/lld/test/ELF/aarch64-tls-le.s+23-6
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
4# RUN: llvm-objdump -d %tout | FileCheck %s4# RUN: llvm-objdump -d %tout | FileCheck %s
5# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s5# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
66
7#Local-Dynamic to Initial-Exec relax creates no7#Local-Dynamic to Local-Exec relax creates no
8#RELOC: Relocations [8#RELOC: Relocations [
9#RELOC-NEXT: ]9#RELOC-NEXT: ]
1010
...@@ -13,19 +13,36 @@ _start:...@@ -13,19 +13,36 @@ _start:
13 mrs x0, TPIDR_EL013 mrs x0, TPIDR_EL0
14 add x0, x0, :tprel_hi12:v114 add x0, x0, :tprel_hi12:v1
15 add x0, x0, :tprel_lo12_nc:v115 add x0, x0, :tprel_lo12_nc:v1
16 mrs x0, TPIDR_EL0
17 add x0, x0, :tprel_hi12:v2
18 add x0, x0, :tprel_lo12_nc:v2
1619
17# TCB size = 0x16 and foo is first element from TLS register.20# TCB size = 64 and foo is first element from TLS register.
18#CHECK: Disassembly of section .text:21#CHECK: Disassembly of section .text:
19#CHECK: _start:22#CHECK: _start:
20#CHECK: 20000: 40 d0 3b d5 mrs x0, TPIDR_EL023#CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0
21#CHECK: 20004: 00 00 40 91 add x0, x0, #0, lsl #1224#CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12
22#CHECK: 20008: 00 40 00 91 add x0, x0, #1625#CHECK: 210008: 00 00 01 91 add x0, x0, #64
26#CHECK: 21000c: 40 d0 3b d5 mrs x0, TPIDR_EL0
27#CHECK: 210010: 00 fc 7f 91 add x0, x0, #4095, lsl #12
28#CHECK: 210014: 00 e0 3f 91 add x0, x0, #4088
2329
24.type v1,@object
25.section .tbss,"awT",@nobits30.section .tbss,"awT",@nobits
31
32.type v1,@object
26.globl v133.globl v1
27.p2align 234.p2align 2
28v1:35v1:
29.word 036.word 0
30.size v1, 437.size v1, 4
3138
39# The current offset from the thread pointer is 68. Raise it to just below the
40# 24-bit limit.
41.space (0xfffff8 - 68)
42
43.type v2,@object
44.globl v2
45.p2align 2
46v2:
47.word 0
48.size v2, 4
deps/lld/test/ELF/aarch64-tlsld-ldst.s+26-26
...@@ -25,28 +25,28 @@ _start: mrs x8, TPIDR_EL0...@@ -25,28 +25,28 @@ _start: mrs x8, TPIDR_EL0
25 ldrb w0, [x8, :tprel_lo12_nc:var4]25 ldrb w0, [x8, :tprel_lo12_nc:var4]
2626
27// CHECK: _start:27// CHECK: _start:
28// CHECK-NEXT: 20000: 48 d0 3b d5 mrs x8, TPIDR_EL028// CHECK-NEXT: 210000: 48 d0 3b d5 mrs x8, TPIDR_EL0
29// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var029// 0x0 + c40 = 0xc40 = tcb (64-bytes) + var0
30// CHECK-NEXT: 20004: 08 01 40 91 add x8, x8, #0, lsl #1230// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
31// CHECK-NEXT: 20008: 14 05 c3 3d ldr q20, [x8, #3088]31// CHECK-NEXT: 210008: 14 11 c3 3d ldr q20, [x8, #3136]
32// 0x1000 + 0x820 = 0x1820 = tcb + var132// 0x1000 + 0x850 = 0x1850 = tcb + var1
33// CHECK-NEXT: 2000c: 08 05 40 91 add x8, x8, #1, lsl #1233// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
34// CHECK-NEXT: 20010: 00 11 44 f9 ldr x0, [x8, #2080]34// CHECK-NEXT: 210010: 00 29 44 f9 ldr x0, [x8, #2128]
35// 0x2000 + 0x428 = 0x2428 = tcb + var235// 0x2000 + 0x458 = 0x2458 = tcb + var2
36// CHECK-NEXT: 20014: 08 09 40 91 add x8, x8, #2, lsl #1236// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
37// CHECK-NEXT: 20018: 00 29 44 b9 ldr w0, [x8, #1064]37// CHECK-NEXT: 210018: 00 59 44 b9 ldr w0, [x8, #1112]
38// 0x3000 + 0x2c = 0x302c = tcb + var338// 0x3000 + 0x5c = 0x305c = tcb + var3
39// CHECK-NEXT: 2001c: 08 0d 40 91 add x8, x8, #3, lsl #1239// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
40// CHECK-NEXT: 20020: 00 59 40 79 ldrh w0, [x8, #44]40// CHECK-NEXT: 210020: 00 b9 40 79 ldrh w0, [x8, #92]
41// 0x3000 + 0xc2e = 0x32ce = tcb + var441// 0x3000 + 0xc5e = 0x3c5e = tcb + var4
42// CHECK-NEXT: 20024: 08 0d 40 91 add x8, x8, #3, lsl #1242// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
43// CHECK-NEXT: 20028: 00 b9 70 39 ldrb w0, [x8, #3118]43// CHECK-NEXT: 210028: 00 79 71 39 ldrb w0, [x8, #3166]
4444
45// CHECK-SYMS: 0000000000000c00 0 TLS GLOBAL DEFAULT 2 var045// CHECK-SYMS: 0000000000000c00 16 TLS GLOBAL DEFAULT 2 var0
46// CHECK-SYMS-NEXT: 0000000000001810 4 TLS GLOBAL DEFAULT 2 var146// CHECK-SYMS-NEXT: 0000000000001810 8 TLS GLOBAL DEFAULT 2 var1
47// CHECK-SYMS-NEXT: 0000000000002418 2 TLS GLOBAL DEFAULT 2 var247// CHECK-SYMS-NEXT: 0000000000002418 4 TLS GLOBAL DEFAULT 2 var2
48// CHECK-SYMS-NEXT: 000000000000301c 1 TLS GLOBAL DEFAULT 2 var348// CHECK-SYMS-NEXT: 000000000000301c 2 TLS GLOBAL DEFAULT 2 var3
49// CHECK-SYMS-NEXT: 0000000000003c1e 0 TLS GLOBAL DEFAULT 2 var449// CHECK-SYMS-NEXT: 0000000000003c1e 1 TLS GLOBAL DEFAULT 2 var4
5050
51 .globl var051 .globl var0
52 .globl var152 .globl var1
...@@ -59,12 +59,12 @@ _start: mrs x8, TPIDR_EL0...@@ -59,12 +59,12 @@ _start: mrs x8, TPIDR_EL0
59 .type var3,@object59 .type var3,@object
6060
61.section .tbss,"awT",@nobits61.section .tbss,"awT",@nobits
62 .balign 1662 .balign 64
63 .space 1024 * 363 .space 1024 * 3
64var0:64var0:
65 .quad 065 .quad 0
66 .quad 066 .quad 0
67 .size var1, 1667 .size var0, 16
68 .space 1024 * 368 .space 1024 * 3
69var1:69var1:
70 .quad 070 .quad 0
...@@ -72,14 +72,14 @@ var1:...@@ -72,14 +72,14 @@ var1:
72 .space 1024 * 372 .space 1024 * 3
73var2:73var2:
74 .word 074 .word 0
75 .size var1, 475 .size var2, 4
7676
77 .space 1024 * 377 .space 1024 * 3
78var3:78var3:
79 .hword 079 .hword 0
80 .size var2, 280 .size var3, 2
81 .space 1024 * 381 .space 1024 * 3
82var4:82var4:
83 .byte 083 .byte 0
84 .size var3, 184 .size var4, 1
85 .space 1024 * 385 .space 1024 * 3
deps/lld/test/ELF/aarch64-tstbr14-reloc.s+15-11
...@@ -13,19 +13,19 @@...@@ -13,19 +13,19 @@
13# 0x11028 - 24 = 0x2001013# 0x11028 - 24 = 0x20010
14# CHECK: Disassembly of section .text:14# CHECK: Disassembly of section .text:
15# CHECK-NEXT: _foo:15# CHECK-NEXT: _foo:
16# CHECK-NEXT: 20000: {{.*}} nop16# CHECK-NEXT: 210000: {{.*}} nop
17# CHECK-NEXT: 20004: {{.*}} nop17# CHECK-NEXT: 210004: {{.*}} nop
18# CHECK-NEXT: 20008: {{.*}} nop18# CHECK-NEXT: 210008: {{.*}} nop
19# CHECK-NEXT: 2000c: {{.*}} nop19# CHECK-NEXT: 21000c: {{.*}} nop
20# CHECK: _bar:20# CHECK: _bar:
21# CHECK-NEXT: 20010: {{.*}} nop21# CHECK-NEXT: 210010: {{.*}} nop
22# CHECK-NEXT: 20014: {{.*}} nop22# CHECK-NEXT: 210014: {{.*}} nop
23# CHECK-NEXT: 20018: {{.*}} nop23# CHECK-NEXT: 210018: {{.*}} nop
24# CHECK: _start:24# CHECK: _start:
25# CHECK-NEXT: 2001c: {{.*}} tbnz w3, #15, #-2825# CHECK-NEXT: 21001c: {{.*}} tbnz w3, #15, #-28
26# CHECK-NEXT: 20020: {{.*}} tbnz w3, #15, #-1626# CHECK-NEXT: 210020: {{.*}} tbnz w3, #15, #-16
27# CHECK-NEXT: 20024: {{.*}} tbz x6, #45, #-3627# CHECK-NEXT: 210024: {{.*}} tbz x6, #45, #-36
28# CHECK-NEXT: 20028: {{.*}} tbz x6, #45, #-2428# CHECK-NEXT: 210028: {{.*}} tbz x6, #45, #-24
2929
30#DSOREL: Section {30#DSOREL: Section {
31#DSOREL: Index:31#DSOREL: Index:
...@@ -79,10 +79,14 @@...@@ -79,10 +79,14 @@
79#DSO-NEXT: 10044: {{.*}} nop79#DSO-NEXT: 10044: {{.*}} nop
80#DSO-NEXT: 10048: {{.*}} nop80#DSO-NEXT: 10048: {{.*}} nop
81#DSO-NEXT: 1004c: {{.*}} nop81#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-EMPTY:
83#DSO-NEXT: _foo@plt:
82#DSO-NEXT: 10050: {{.*}} adrp x16, #6553684#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
83#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]85#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
84#DSO-NEXT: 10058: {{.*}} add x16, x16, #2486#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
85#DSO-NEXT: 1005c: {{.*}} br x1787#DSO-NEXT: 1005c: {{.*}} br x17
88#DSO-EMPTY:
89#DSO-NEXT: _bar@plt:
86#DSO-NEXT: 10060: {{.*}} adrp x16, #6553690#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
87#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]91#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
88#DSO-NEXT: 10068: {{.*}} add x16, x16, #3292#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
deps/lld/test/ELF/aarch64-undefined-weak.s+12-12
...@@ -34,16 +34,16 @@ _start:...@@ -34,16 +34,16 @@ _start:
34 ldr x8, target34 ldr x8, target
3535
36// CHECK: Disassembly of section .text:36// CHECK: Disassembly of section .text:
37// 131072 = 0x2000037// 2162688 = 0x210000
38// CHECK: 20000: {{.*}} b #438// CHECK: 210000: {{.*}} b #4
39// CHECK-NEXT: 20004: {{.*}} bl #439// CHECK-NEXT: 210004: {{.*}} bl #4
40// CHECK-NEXT: 20008: {{.*}} b.eq #440// CHECK-NEXT: 210008: {{.*}} b.eq #4
41// CHECK-NEXT: 2000c: {{.*}} cbz x1, #441// CHECK-NEXT: 21000c: {{.*}} cbz x1, #4
42// CHECK-NEXT: 20010: {{.*}} adr x0, #042// CHECK-NEXT: 210010: {{.*}} adr x0, #0
43// CHECK-NEXT: 20014: {{.*}} adrp x0, #-13107243// CHECK-NEXT: 210014: {{.*}} adrp x0, #0
44// CHECK: 20018: {{.*}} .word 0x0000000044// CHECK: 210018: {{.*}} .word 0x00000000
45// CHECK-NEXT: 2001c: {{.*}} .word 0x0000000045// CHECK-NEXT: 21001c: {{.*}} .word 0x00000000
46// CHECK-NEXT: 20020: {{.*}} .word 0x0000000046// CHECK-NEXT: 210020: {{.*}} .word 0x00000000
47// CHECK-NEXT: 20024: {{.*}} .short 0x000047// CHECK-NEXT: 210024: {{.*}} .short 0x0000
48// CHECK: $x.2:48// CHECK: $x.2:
49// CHECK-NEXT: 20026: {{.*}} ldr x8, #049// CHECK-NEXT: 210026: {{.*}} ldr x8, #0
deps/lld/test/ELF/amdgpu-elf-flags-err.s+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1# REQUIRES: amdgpu1# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx802 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx802 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o
3# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o3# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o
4# RUN: not ld.lld -shared %t-0.o %t-1.o -o /dev/null 2>&1 | FileCheck %s4# RUN: not ld.lld -shared %t-0.o %t-1.o -o /dev/null 2>&1 | FileCheck %s
55
6# CHECK: error: incompatible e_flags: {{.*}}-1.o6# CHECK: error: incompatible e_flags: {{.*}}-1.o
deps/lld/test/ELF/amdgpu-elf-flags.s+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1# REQUIRES: amdgpu1# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o
3# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o3# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o
4# RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so4# RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so
5# RUN: llvm-readobj -file-headers %t.so | FileCheck %s5# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
66
deps/lld/test/ELF/amdgpu-kernels.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1# REQUIRES: amdgpu1# REQUIRES: amdgpu
2# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o2# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -mattr=-code-object-v3 %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t3# RUN: ld.lld -shared %t.o -o %t
4# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s4# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
55
deps/lld/test/ELF/archive-fetch.s created+15
...@@ -0,0 +1,15 @@
1# REQUIRES: x86
2
3# We have a code in LLD that prevents fetching the same object from archive file twice.
4# This test triggers that code, without it we would fail to link output.
5
6# RUN: echo '.globl foo, bar; foo:' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tfoo.o
7# RUN: echo '.globl foo, bar; bar:' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tbar.o
8# RUN: rm -f %t.a
9# RUN: llvm-ar rcs %t.a %tfoo.o %tbar.o
10
11# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
12# RUN: ld.lld %t.a %t.o -o /dev/null
13
14_start:
15callq foo
deps/lld/test/ELF/arm-bl-v6-inrange.s created+47
...@@ -0,0 +1,47 @@
1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \
4// RUN: .callee1 0x100004 : { *(.callee_low) } \
5// RUN: .caller 0x500000 : { *(.text) } \
6// RUN: .callee2 0x900004 : { *(.callee_high) } } " > %t.script
7// RUN: ld.lld %t --script %t.script -o %t2 2>&1
8// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
9// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
10
11// On older Arm Architectures such as v5 and v6 the Thumb BL and BLX relocation
12// uses a slightly different encoding that has a lower range. These relocations
13// are at the extreme range of what is permitted.
14 .thumb
15 .text
16 .syntax unified
17 .cpu arm1176jzf-s
18 .globl _start
19 .type _start,%function
20_start:
21 bl thumbfunc
22 bl armfunc
23 bx lr
24
25 .section .callee_low, "ax", %progbits
26 .globl thumbfunc
27 .type thumbfunc, %function
28thumbfunc:
29 bx lr
30// CHECK-THUMB: Disassembly of section .callee1:
31// CHECK-THUMB-NEXT: thumbfunc:
32// CHECK-THUMB-NEXT: 100004: 70 47 bx lr
33// CHECK-THUMB-NEXT: Disassembly of section .caller:
34// CHECK-THUMB-NEXT: _start:
35// CHECK-THUMB-NEXT: 500000: 00 f4 00 f8 bl #-4194304
36// CHECK-THUMB-NEXT: 500004: ff f3 fe ef blx #4194300
37// CHECK-THUMB-NEXT: 500008: 70 47 bx lr
38
39 .arm
40 .section .callee_high, "ax", %progbits
41 .globl armfunc
42 .type armfunc, %function
43armfunc:
44 bx lr
45// CHECK-ARM: Disassembly of section .callee2:
46// CHECK-ARM-NEXT: armfunc:
47// CHECK-ARM-NEXT: 900004: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-bl-v6.s+23-10
...@@ -1,22 +1,23 @@...@@ -1,22 +1,23 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s3// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=69632 -stop-address=69640 %t2 | FileCheck -check-prefix=CHECK-ARM1 %s
5// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=69640 -stop-address=69644 | FileCheck -check-prefix=CHECK-THUMB1 %s
6// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=2166796 -stop-address=2166804 %t2 | FileCheck -check-prefix=CHECK-ARM2 %s
7// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=6365184 -stop-address=6365186 | FileCheck -check-prefix=CHECK-THUMB2 %s
48
5// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the9// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
6// extended range encoding is not supported. The following example has a Thumb10// extended range encoding is not supported. The following example has a Thumb
7// BL that is out of range on ARM v6 and requires a range extension thunk.11// BL that is out of range on ARM v6 and requires a range extension thunk.
8// As v6 does not support MOVT or MOVW instructions the Thunk must not12// As v6 does not support MOVT or MOVW instructions the Thunk must not
9// use these instructions either. At present we don't support v6 so we give a13// use these instructions either.
10// warning for unsupported features.14
1115
12// CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
13// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
14// ARM v6 supports blx so we shouldn't see the blx not supported warning.16// ARM v6 supports blx so we shouldn't see the blx not supported warning.
15// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.17// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
16 .text18 .text
17 .syntax unified19 .syntax unified
18 .cpu arm1176jzf-s20 .cpu arm1176jzf-s
19 .eabi_attribute 6, 6 @ Tag_CPU_arch
20 .globl _start21 .globl _start
21 .type _start,%function22 .type _start,%function
22 .balign 0x100023 .balign 0x1000
...@@ -24,6 +25,10 @@ _start:...@@ -24,6 +25,10 @@ _start:
24 bl thumbfunc25 bl thumbfunc
25 bx lr26 bx lr
2627
28// CHECK-ARM1: Disassembly of section .text:
29// CHECK-ARM1-NEXT: _start:
30// CHECK-ARM1-NEXT: 11000: 00 00 00 fa blx #0 <thumbfunc>
31// CHECK-ARM1-NEXT: 11004: 1e ff 2f e1 bx lr
27 .thumb32 .thumb
28 .section .text.2, "ax", %progbits33 .section .text.2, "ax", %progbits
29 .globl thumbfunc34 .globl thumbfunc
...@@ -31,11 +36,17 @@ _start:...@@ -31,11 +36,17 @@ _start:
31thumbfunc:36thumbfunc:
32 bl farthumbfunc37 bl farthumbfunc
3338
34// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v639// CHECK-THUMB1: thumbfunc:
35// Arm, but not on a v7 Arm.40// CHECK-THUMB1-NEXT: 11008: 00 f2 00 e8 blx #2097152
41// 6 Megabytes, enough to make farthumbfunc out of range of caller
42// on a v6 Arm, but not on a v7 Arm.
43
36 .section .text.3, "ax", %progbits44 .section .text.3, "ax", %progbits
37 .space 0x20000045 .space 0x200000
3846// CHECK-ARM2: __ARMv5ABSLongThunk_farthumbfunc:
47// CHECK-ARM2-NEXT: 21100c: 04 f0 1f e5 ldr pc, [pc, #-4]
48// CHECK-ARM2: $d:
49// CHECK-ARM2-NEXT: 211010: 01 20 61 00 .word 0x00612001
39 .section .text.4, "ax", %progbits50 .section .text.4, "ax", %progbits
40 .space 0x20000051 .space 0x200000
4152
...@@ -49,3 +60,5 @@ thumbfunc:...@@ -49,3 +60,5 @@ thumbfunc:
49 .type farthumbfunc,%function60 .type farthumbfunc,%function
50farthumbfunc:61farthumbfunc:
51 bx lr62 bx lr
63// CHECK-THUMB2: farthumbfunc:
64// CHECK-THUMB2-NEXT: 612000: 70 47 bx lr
deps/lld/test/ELF/arm-blx-v4t.s+2-5
...@@ -1,19 +1,16 @@...@@ -1,19 +1,16 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s3// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
44
5// On Arm v4t there is no blx instruction so all interworking must go via5// On Arm v4t there is no blx instruction so all interworking must go via
6// a thunk. At present we don't support v4t so we give a warning for unsupported6// a thunk. At present we don't support v4t so we give a warning for unsupported
7// features.7// features.
88
9// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected.9// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected
10// CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
11// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
1210
13 .text11 .text
14 .syntax unified12 .syntax unified
15 .cpu arm7tdmi13 .cpu arm7tdmi
16 .eabi_attribute 6, 2 @ Tag_CPU_arch
17 .arm14 .arm
18 .globl _start15 .globl _start
19 .type _start,%function16 .type _start,%function
deps/lld/test/ELF/arm-branch-rangethunk.s+3-3
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
4// RUN: ld.lld %t %tfar -o %t2 2>&14// RUN: ld.lld %t %tfar -o %t2 2>&1
5// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s5// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s
6// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong6// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
7// RUN: ld.lld %t %tfarlong -o %t3 2>&17// RUN: ld.lld %t %tfarlong -o %t3 2>&1
8// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s8// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s
9 .syntax unified9 .syntax unified
deps/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s+2-2
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
3// RUN: ld.lld %t --shared -o %t.so3// RUN: ld.lld %t --shared -o %t.so
4// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t24// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
5// RUN: ld.lld %t2 %t.so -o %t35// RUN: ld.lld %t2 %t.so -o %t3
6// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s6// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s
77
deps/lld/test/ELF/arm-combined-dynrel-ifunc.s created+49
...@@ -0,0 +1,49 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-linux-gnueabihf %p/Inputs/arm-shared.s -o %t-lib.o
3// RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-linux-gnueabihf %s -o %t.o
4// RUN: ld.lld %t-lib.o --shared -o %t.so
5// RUN: echo "SECTIONS { \
6// RUN: .text : { *(.text) } \
7// RUN: .rela.dyn : { *(.rel.dyn) *(.rel.plt) } \
8// RUN: } " > %t.script
9// RUN: ld.lld %t.o -o %t.axf %t.so --script %t.script
10// RUN: llvm-readobj --section-headers --dynamic-table %t.axf | FileCheck %s
11
12// The linker script above combines the .rela.dyn and .rela.plt into a single
13// table. ELF is clear that the DT_PLTRELSZ should match the subset of
14// relocations that is associated with the PLT. It is less clear about what
15// the value of DT_RELASZ should be. ELF implies that it should be the size
16// of the single table so that DT_RELASZ includes DT_PLTRELSZ. The loader in
17// glibc permits this as long as .rela.plt comes after .rela.dyn in the
18// combined table. In the ARM case irelative relocations do not count as PLT
19// relocs.
20
21.text
22.globl indirect
23.type indirect,%gnu_indirect_function
24indirect:
25 bx lr
26
27.globl bar2 // from Inputs/arm-shared.s
28
29.text
30.globl _start
31.type _start,%function
32main:
33 bl indirect
34 bl bar2
35 .word indirect(got)
36 .word bar2(got)
37 bx lr
38
39// CHECK: Name: .rela.dyn
40// CHECK-NEXT: Type: SHT_REL
41// CHECK-NEXT: Flags [
42// CHECK-NEXT: SHF_ALLOC
43// CHECK-NEXT: ]
44// CHECK-NEXT: Address:
45// CHECK-NEXT: Offset:
46// CHECK-NEXT: Size: 24
47
48// CHECK: 0x00000012 RELSZ 24 (bytes)
49// CHECK: 0x00000002 PLTRELSZ 8 (bytes)
deps/lld/test/ELF/arm-extreme-range-pi-thunk.s created+82
...@@ -0,0 +1,82 @@
1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS {" > %t.script
4// RUN: echo " .text_low 0x130 : { *(.text) }" >> %t.script
5// RUN: echo " .text_high 0xf0000000 : AT(0x1000) { *(.text_high) }" >> %t.script
6// RUN: echo " } " >> %t.script
7// RUN: ld.lld --script %t.script --pie --static %t -o %t2 2>&1
8// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
9
10// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t3
11// RUN: ld.lld --script %t.script --pie %t3 -o %t4 2>&1
12// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB %s
13
14// Check that we can create Arm and Thumb v7a Position Independent Thunks that
15// can span the address space without triggering overflow errors. We use an
16// AT(0x1000) for .text_high to avoid creating an almost 4Gb size file.
17 .syntax unified
18 .text
19 .global _start
20 .type _start, %function
21_start:
22 bl high
23 bx lr
24
25 .section .text_high, "ax", %progbits
26 .global high
27 .type high, %function
28high:
29 bl _start
30 bx lr
31
32// ARMv7a instructions and relocations.
33
34// CHECK: Disassembly of section .text_low:
35// CHECK-NEXT: _start:
36// CHECK-NEXT: 130: 00 00 00 eb bl #0 <__ARMV7PILongThunk_high>
37// CHECK-NEXT: 134: 1e ff 2f e1 bx lr
38
39// CHECK: __ARMV7PILongThunk_high:
40// CHECK-NEXT: 138: b8 ce 0f e3 movw r12, #65208
41// CHECK-NEXT: 13c: ff cf 4e e3 movt r12, #61439
42// 0x140 + 0xEFFF0000 + 0x0000FEB8 + 8 = 0xf0000000 = high
43// CHECK-NEXT: 140: 0f c0 8c e0 add r12, r12, pc
44// CHECK-NEXT: 144: 1c ff 2f e1 bx r12
45
46// CHECK: Disassembly of section .text_high:
47// CHECK-NEXT: high:
48// CHECK-NEXT: f0000000: 00 00 00 eb bl #0 <__ARMV7PILongThunk__start>
49// CHECK-NEXT: f0000004: 1e ff 2f e1 bx lr
50
51// CHECK: __ARMV7PILongThunk__start:
52// CHECK-NEXT: f0000008: 18 c1 00 e3 movw r12, #280
53// CHECK-NEXT: f000000c: 00 c0 41 e3 movt r12, #4096
54// 0xf0000010 + 0x10000000 + 0x0000118 + 8 = bits32(0x100000130),0x130 = _start
55// CHECK-NEXT: f0000010: 0f c0 8c e0 add r12, r12, pc
56// CHECK-NEXT: f0000014: 1c ff 2f e1 bx r12
57
58// Thumbv7a instructions and relocations
59// CHECK-THUMB: Disassembly of section .text_low:
60// CHECK-THUMB-NEXT: _start:
61// CHECK-THUMB-NEXT: 130: 00 f0 02 f8 bl #4
62// CHECK-THUMB-NEXT: 134: 70 47 bx lr
63// CHECK-THUMB-NEXT: 136: d4 d4 bmi #-88
64
65// CHECK-THUMB: __ThumbV7PILongThunk_high:
66// CHECK-THUMB-NEXT: 138: 4f f6 bd 6c movw r12, #65213
67// CHECK-THUMB-NEXT: 13c: ce f6 ff 7c movt r12, #61439
68// 0x140 + 0xEFFF0000 + 0x0000FEBD + 4 = 0xf0000001 = high
69// CHECK-THUMB-NEXT: 140: fc 44 add r12, pc
70// CHECK-THUMB-NEXT: 142: 60 47 bx r12
71
72// CHECK-THUMB: Disassembly of section .text_high:
73// CHECK-THUMB-NEXT: high:
74// CHECK-THUMB-NEXT: f0000000: 00 f0 02 f8 bl #4
75// CHECK-THUMB-NEXT: f0000004: 70 47 bx lr
76
77// CHECK-THUMB: __ThumbV7PILongThunk__start:
78// CHECK-THUMB-NEXT: f0000008: 40 f2 1d 1c movw r12, #285
79// CHECK-THUMB-NEXT: f000000c: c1 f2 00 0c movt r12, #4096
80// 0xf0000010 + 0x10000000 + 0x000011d +4 = bits32(0x100000131),0x131 = _start
81// CHECK-THUMB-NEXT: f0000010: fc 44 add r12, pc
82// CHECK-THUMB-NEXT: f0000012: 60 47 bx r12
deps/lld/test/ELF/arm-force-pi-thunk.s created+87
...@@ -0,0 +1,87 @@
1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .text_low : { *(.text_low) *(.text_low2) } \
6// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
7// RUN: } " > %t.script
8// RUN: ld.lld --pic-veneer --script %t.script %t -o %t2 2>&1
9// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
10
11// Test that we can force generation of position independent thunks even when
12// inputs are not pic.
13
14 .syntax unified
15 .section .text_low, "ax", %progbits
16 .thumb
17 .globl _start
18_start: bx lr
19 .globl low_target
20 .type low_target, %function
21low_target:
22 bl high_target
23 bl high_target2
24
25 .section .text_low2, "ax", %progbits
26 .thumb
27 .globl low_target2
28 .type low_target2, %function
29low_target2:
30 bl high_target
31 bl high_target2
32
33// CHECK: Disassembly of section .text_low:
34// CHECK-NEXT: _start:
35// CHECK-NEXT: 94: 70 47 bx lr
36// CHECK: low_target:
37// CHECK-NEXT: 96: 00 f0 03 f8 bl #6
38// CHECK-NEXT: 9a: 00 f0 07 f8 bl #14
39// CHECK-NEXT: 9e: d4 d4 bmi #-88
40// CHECK: __ThumbV7PILongThunk_high_target:
41// CHECK-NEXT: a0: 4f f6 55 7c movw r12, #65365
42// CHECK-NEXT: a4: c0 f2 ff 1c movt r12, #511
43// CHECK-NEXT: a8: fc 44 add r12, pc
44// CHECK-NEXT: aa: 60 47 bx r12
45// CHECK: __ThumbV7PILongThunk_high_target2:
46// CHECK-NEXT: ac: 4f f6 69 7c movw r12, #65385
47// CHECK-NEXT: b0: c0 f2 ff 1c movt r12, #511
48// CHECK-NEXT: b4: fc 44 add r12, pc
49// CHECK-NEXT: b6: 60 47 bx r12
50// CHECK: low_target2:
51// CHECK-NEXT: b8: ff f7 f2 ff bl #-28
52// CHECK-NEXT: bc: ff f7 f6 ff bl #-20
53
54
55 .section .text_high, "ax", %progbits
56 .thumb
57 .globl high_target
58 .type high_target, %function
59high_target:
60 bl low_target
61 bl low_target2
62
63 .section .text_high2, "ax", %progbits
64 .thumb
65 .globl high_target2
66 .type high_target2, %function
67high_target2:
68 bl low_target
69 bl low_target2
70
71// CHECK: Disassembly of section .text_high:
72// CHECK-NEXT: high_target:
73// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
74// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12
75// CHECK: __ThumbV7PILongThunk_low_target:
76// CHECK-NEXT: 2000008: 40 f2 83 0c movw r12, #131
77// CHECK-NEXT: 200000c: cf f6 00 6c movt r12, #65024
78// CHECK-NEXT: 2000010: fc 44 add r12, pc
79// CHECK-NEXT: 2000012: 60 47 bx r12
80// CHECK: __ThumbV7PILongThunk_low_target2:
81// CHECK-NEXT: 2000014: 40 f2 99 0c movw r12, #153
82// CHECK-NEXT: 2000018: cf f6 00 6c movt r12, #65024
83// CHECK-NEXT: 200001c: fc 44 add r12, pc
84// CHECK-NEXT: 200001e: 60 47 bx r12
85// CHECK: high_target2:
86// CHECK-NEXT: 2000020: ff f7 f2 ff bl #-28
87// CHECK-NEXT: 2000024: ff f7 f6 ff bl #-20
deps/lld/test/ELF/arm-gnu-ifunc.s+4-1
...@@ -35,6 +35,8 @@ _start:...@@ -35,6 +35,8 @@ _start:
35// CHECK-NEXT: Address: 0x100F435// CHECK-NEXT: Address: 0x100F4
36// CHECK-NEXT: Offset: 0xF436// CHECK-NEXT: Offset: 0xF4
37// CHECK-NEXT: Size: 1637// CHECK-NEXT: Size: 16
38// CHECK-NEXT: Link:
39// CHECK-NEXT: Info: 4
38// CHECK: Name: .plt40// CHECK: Name: .plt
39// CHECK-NEXT: Type: SHT_PROGBITS41// CHECK-NEXT: Type: SHT_PROGBITS
40// CHECK-NEXT: Flags [42// CHECK-NEXT: Flags [
...@@ -44,7 +46,8 @@ _start:...@@ -44,7 +46,8 @@ _start:
44// CHECK-NEXT: Address: 0x1102046// CHECK-NEXT: Address: 0x11020
45// CHECK-NEXT: Offset: 0x102047// CHECK-NEXT: Offset: 0x1020
46// CHECK-NEXT: Size: 3248// CHECK-NEXT: Size: 32
47// CHECK: Name: .got49// CHECK: Index: 4
50// CHECK-NEXT: Name: .got
48// CHECK-NEXT: Type: SHT_PROGBITS51// CHECK-NEXT: Type: SHT_PROGBITS
49// CHECK-NEXT: Flags [52// CHECK-NEXT: Flags [
50// CHECK-NEXT: SHF_ALLOC53// CHECK-NEXT: SHF_ALLOC
deps/lld/test/ELF/arm-long-thunk-converge.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s2// RUN: llvm-mc -triple armv7-unknown-gnu -arm-add-build-attributes -filetype=obj -o %t %s
3// RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t23// RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2
4// RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s4// RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s
5// RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s5// RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s
deps/lld/test/ELF/arm-thumb-branch-rangethunk.s+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
4// RUN: ld.lld %t %tfar -o %t2 2>&14// RUN: ld.lld %t %tfar -o %t2 2>&1
5// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t25// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2
6 .syntax unified6 .syntax unified
deps/lld/test/ELF/arm-thumb-branch.s+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
4// RUN: echo "SECTIONS { \4// RUN: echo "SECTIONS { \
5// RUN: . = 0xb4; \5// RUN: . = 0xb4; \
6// RUN: .callee1 : { *(.callee_low) } \6// RUN: .callee1 : { *(.callee_low) } \
deps/lld/test/ELF/arm-thumb-condbranch-thunk.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thumb-interwork-shared.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t --shared -o %t.so3// RUN: ld.lld %t --shared -o %t.so
4// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s4// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
5// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT5// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT
deps/lld/test/ELF/arm-thumb-interwork-thunk-range.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -o /dev/null -image-base=0x800000003// RUN: ld.lld %t.o -o /dev/null -image-base=0x80000000
44
5// Test that when the thunk is at a high address we don't get confused with it5// Test that when the thunk is at a high address we don't get confused with it
deps/lld/test/ELF/arm-thumb-interwork-thunk-v5.s created+66
...@@ -0,0 +1,66 @@
1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv5-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2
4// RUN: llvm-objdump -d %t2 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM %s
5// RUN: llvm-objdump -d %t2 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB %s
6// RUN: ld.lld %t -o %t3 --shared
7// RUN: llvm-objdump -d %t3 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM-PI %s
8// RUN: llvm-objdump -d %t3 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB-PI %s
9
10// Test ARM Thumb Interworking on older Arm architectures using Thunks that do
11// not use MOVT/MOVW instructions.
12// For pure interworking (not considering range extension) there is only the
13// case of an Arm B to a Thumb Symbol to consider as in older Arm architectures
14// there is no Thumb B.w that we can intercept with a Thunk and we still assume
15// support for the blx instruction for Thumb BL and BLX to an Arm symbol.
16 .arm
17 .text
18 .syntax unified
19 .cpu arm10tdmi
20
21 .text
22 .globl _start
23 .type _start, %function
24 .balign 0x1000
25_start:
26 b thumb_func
27 bl thumb_func
28 blx thumb_func
29 bx lr
30
31// CHECK-ARM: _start:
32// CHECK-ARM-NEXT: 11000: 03 00 00 ea b #12 <__ARMv5ABSLongThunk_thumb_func>
33// CHECK-ARM-NEXT: 11004: 01 00 00 fa blx #4 <thumb_func>
34// CHECK-ARM-NEXT: 11008: 00 00 00 fa blx #0 <thumb_func>
35// CHECK-ARM-NEXT: 1100c: 1e ff 2f e1 bx lr
36
37// CHECK-THUMB: thumb_func:
38// CHECK-THUMB-NEXT: 11010: 70 47 bx lr
39
40// CHECK-ARM: __ARMv5ABSLongThunk_thumb_func:
41// CHECK-ARM-NEXT: 11014: 04 f0 1f e5 ldr pc, [pc, #-4]
42// CHECK-ARM: $d:
43// CHECK-ARM-NEXT: 11018: 11 10 01 00 .word 0x00011011
44
45// CHECK-ARM-PI: _start:
46// CHECK-ARM-PI-NEXT: 1000: 03 00 00 ea b #12 <__ARMV5PILongThunk_thumb_func>
47// CHECK-ARM-PI-NEXT: 1004: 01 00 00 fa blx #4 <thumb_func>
48// CHECK-ARM-PI-NEXT: 1008: 00 00 00 fa blx #0 <thumb_func>
49// CHECK-ARM-PI-NEXT: 100c: 1e ff 2f e1 bx lr
50
51// CHECK-THUMB-PI: thumb_func:
52// CHECK-THUMB-PI-NEXT: 1010: 70 47 bx lr
53
54// CHECK-ARM-PI: __ARMV5PILongThunk_thumb_func:
55// CHECK-ARM-PI-NEXT: 1014: 04 c0 9f e5 ldr r12, [pc, #4]
56// CHECK-ARM-PI-NEXT: 1018: 0c c0 8f e0 add r12, pc, r12
57// CHECK-ARM-PI-NEXT: 101c: 1c ff 2f e1 bx r12
58// CHECK-ARM-PI: $d:
59// CHECK-ARM-PI-NEXT: 1020: f1 ff ff ff .word 0xfffffff1
60
61 .section .text.1, "ax", %progbits
62 .thumb
63 .hidden thumb_func
64 .type thumb_func, %function
65thumb_func:
66 bx lr
deps/lld/test/ELF/arm-thumb-interwork-thunk.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \5// RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \
deps/lld/test/ELF/arm-thumb-mix-range-thunk-os.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thumb-plt-range-thunk-os.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t --shared --icf=all -o %t.so3// RUN: ld.lld %t --shared --icf=all -o %t.so
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thumb-range-thunk-os.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thumb-thunk-empty-pass.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s4// RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
5// RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s5// RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
deps/lld/test/ELF/arm-thumb-thunk-symbols.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
5// RUN: ld.lld --shared %t -o %t3 2>&15// RUN: ld.lld --shared %t -o %t3 2>&1
deps/lld/test/ELF/arm-thumb-thunk-v6m.s created+61
...@@ -0,0 +1,61 @@
1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6m-none-eabi %s -o %t
3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .text_low : { *(.text_low) *(.text_low2) } \
6// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
7// RUN: } " > %t.script
8// RUN: ld.lld --script %t.script %t -o %t2
9// RUN: llvm-objdump -d %t2 -triple=armv6m-none-eabi | FileCheck %s
10// RUN: ld.lld --script %t.script %t -o %t3 --pie
11// RUN: llvm-objdump -d %t3 -triple=armv6m-none-eabi | FileCheck -check-prefix=CHECK-PI %s
12
13// Range extension thunks for Arm Architecture v6m. Only Thumb instructions
14// are permitted which limits the access to instructions that can access the
15// high registers (r8 - r15), this means that the thunks have to spill
16// low registers (r0 - r7) in order to perform the transfer of control.
17
18 .syntax unified
19 .section .text_low, "ax", %progbits
20 .thumb
21 .type _start, %function
22 .balign 4
23 .globl _start
24_start:
25 bl far
26
27 .section .text_high, "ax", %progbits
28 .globl far
29 .type far, %function
30far:
31 bx lr
32
33// CHECK: Disassembly of section .text_low:
34// CHECK-NEXT: _start:
35// CHECK-NEXT: 94: 00 f0 00 f8 bl #0
36// CHECK: __Thumbv6MABSLongThunk_far:
37// CHECK-NEXT: 98: 03 b4 push {r0, r1}
38// CHECK-NEXT: 9a: 01 48 ldr r0, [pc, #4]
39// CHECK-NEXT: 9c: 01 90 str r0, [sp, #4]
40// CHECK-NEXT: 9e: 01 bd pop {r0, pc}
41// CHECK: a0: 01 00 00 02 .word 0x02000001
42// CHECK: Disassembly of section .text_high:
43// CHECK-NEXT: far:
44// CHECK-NEXT: 2000000: 70 47 bx lr
45
46// CHECK-PI: Disassembly of section .text_low:
47// CHECK-PI-NEXT: _start:
48// CHECK-PI-NEXT: 130: 00 f0 00 f8 bl #0
49// CHECK-PI: __Thumbv6MPILongThunk_far:
50// CHECK-PI-NEXT: 134: 01 b4 push {r0}
51// CHECK-PI-NEXT: 136: 02 48 ldr r0, [pc, #8]
52// CHECK-PI-NEXT: 138: 84 46 mov r12, r0
53// CHECK-PI-NEXT: 13a: 01 bc pop {r0}
54// pc = pc (0x13c + 4) + r12 (1fffec1) = 0x2000001 = .far
55// CHECK-PI-NEXT: 13c: e7 44 add pc, r12
56// CHECK-PI-NEXT: 13e: c0 46 mov r8, r8
57// CHECK-PI: 140: c1 fe ff 01 .word 0x01fffec1
58
59// CHECK-PI: Disassembly of section .text_high:
60// CHECK-PI-NEXT: far:
61// CHECK-PI-NEXT: 2000000: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-undefined-weak-narrow.test created+50
...@@ -0,0 +1,50 @@
1# REQUIRES: arm
2# RUN: yaml2obj %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -triple=thumbv7a-linux-gnueabi -d %t | FileCheck %s
5
6# CHECK: Disassembly of section .text:
7# CHECK-NEXT:_start:
8# CHECK-NEXT: 11000: ff e7 b #-2
9
10# Test the R_ARM_THM_JUMP11 relocation (102) to an undefined weak reference
11# It should resolve to the next instruction, which is an offset of -2 which
12# when added to the Thumb PC-bias of 4 is +2. We can't use llvm-mc to construct
13# the object as it relaxes b.n to b.w (R_ARM_JUMP24).
14
15!ELF
16FileHeader:
17 Class: ELFCLASS32
18 Data: ELFDATA2LSB
19 Type: ET_REL
20 Machine: EM_ARM
21Sections:
22 - Type: SHT_PROGBITS
23 Name: .text
24 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
25 Content: "fee7"
26 - Type: SHT_REL
27 Name: .rel.text
28 Link: .symtab
29 Info: .text
30 Relocations:
31 - Offset: 0
32 Symbol: undefined_weak
33 Type: R_ARM_THM_JUMP11
34
35Symbols:
36 Global:
37 - Type: STT_FUNC
38 Name: _start
39 Value: 1
40 Section: .text
41 Local:
42 - Type: STT_NOTYPE
43 Name: "$t"
44 Section: .text
45 Value: 0
46 Weak:
47 - Type: STT_NOTYPE
48 Name: undefined_weak
49 Value: 0
50
deps/lld/test/ELF/arm-thunk-edgecase.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: .text_armfunc 0x1000 : { *(.text_armfunc) } \4// RUN: .text_armfunc 0x1000 : { *(.text_armfunc) } \
5// RUN: .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \5// RUN: .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \
deps/lld/test/ELF/arm-thunk-largesection.s+7-4
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s4// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s
5// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s5// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s
...@@ -16,9 +16,12 @@ _start:...@@ -16,9 +16,12 @@ _start:
16 bx lr16 bx lr
17 .space 0x100017 .space 0x1000
18// CHECK1: Disassembly of section .text:18// CHECK1: Disassembly of section .text:
19// CHECK1-NEXT: _start:19// CHECK1-NEXT:_start:
20// CHECK1-NEXT: 11000: 70 47 bx lr20// CHECK1-NEXT: 11000: 70 47 bx lr
21// CHECK1-NEXT: 11002: 00 00 movs r0, r021// CHECK1-EMPTY:
22// CHECK-NEXT:$d.1:
23// CHECK-NEXT: 11002: 00 00 .short 0x0000
24
2225
23// CHECK2: __Thumbv7ABSLongThunk__start:26// CHECK2: __Thumbv7ABSLongThunk__start:
24// CHECK2-NEXT: 12004: fe f7 fc bf b.w #-4104 <_start>27// CHECK2-NEXT: 12004: fe f7 fc bf b.w #-4104 <_start>
deps/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \5// RUN: .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \
deps/lld/test/ELF/arm-thunk-linkerscript-large.s+3-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: .text 0x100000 : { *(.text) } \4// RUN: .text 0x100000 : { *(.text) } \
5// RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \5// RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \
...@@ -21,7 +21,8 @@...@@ -21,7 +21,8 @@
21// per OutputSection basis21// per OutputSection basis
22 .syntax unified22 .syntax unified
2323
24// Define a function that we can match with .text_l* aligned on a megabyte // boundary24// Define a function that we can match with .text_l* aligned on a megabyte
25// boundary
25 .macro FUNCTIONL suff26 .macro FUNCTIONL suff
26 .section .text_l\suff\(), "ax", %progbits27 .section .text_l\suff\(), "ax", %progbits
27 .thumb28 .thumb
deps/lld/test/ELF/arm-thunk-linkerscript-orphan.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: .text_low 0x100000 : { *(.text_low) } \4// RUN: .text_low 0x100000 : { *(.text_low) } \
5// RUN: .text_high 0x2000000 : { *(.text_high) } \5// RUN: .text_high 0x2000000 : { *(.text_high) } \
deps/lld/test/ELF/arm-thunk-linkerscript-sort.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \4// RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \
5// RUN: }" > %t.script5// RUN: }" > %t.script
deps/lld/test/ELF/arm-thunk-linkerscript.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .text_low : { *(.text_low) *(.text_low2) } \5// RUN: .text_low : { *(.text_low) *(.text_low2) } \
deps/lld/test/ELF/arm-thunk-multipass.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&13// RUN: ld.lld %t -o %t2 2>&1
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thunk-nosuitable.s+2-3
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1// REQUIRES: ARM1// REQUIRES: arm
2// RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7a-linux-gnueabihf --filetype=obj -o %t.o2// RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7a-linux-gnueabihf --filetype=obj -o %t.o
3// RUN: ld.lld %t.o -o %t3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-objdump -triple=thumbv7a-linux-gnueabihf -d -start-address=2166784 -stop-address=2166794 %t | FileCheck %s4// RUN: llvm-objdump -triple=thumbv7a-linux-gnueabihf -d -start-address=2166784 -stop-address=2166794 %t | FileCheck %s
...@@ -23,8 +23,7 @@ _start:...@@ -23,8 +23,7 @@ _start:
23// CHECK-NEXT: 211000: 00 f0 00 80 beq.w #023// CHECK-NEXT: 211000: 00 f0 00 80 beq.w #0
24// CHECK: __Thumbv7ABSLongThunk_target:24// CHECK: __Thumbv7ABSLongThunk_target:
25// CHECK-NEXT: 211004: 00 f0 01 90 b.w #1258291425// CHECK-NEXT: 211004: 00 f0 01 90 b.w #12582914
26// CHECK: $t.1:26// CHECK: 211008: 70 47 bx lr
27// CHECK-NEXT: 211008: 70 47 bx lr
2827
29 .section .text.2, "ax", %progbits28 .section .text.2, "ax", %progbits
30 .space 12 * 1024 * 102429 .space 12 * 1024 * 1024
deps/lld/test/ELF/arm-thunk-re-add.s+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// REQUIRES: arm1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t --shared -o %t.so3// RUN: ld.lld %t --shared -o %t.so
4// The output file is large, most of it zeroes. We dissassemble only the4// The output file is large, most of it zeroes. We dissassemble only the
5// parts we need to speed up the test and avoid a large output file5// parts we need to speed up the test and avoid a large output file
deps/lld/test/ELF/arm-thunk-section-too-large.s+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1// REQUIRES: ARM1// REQUIRES: arm
2// RUN: llvm-mc %s -triple=armv7a-linux-gnueabihf -arm-add-build-attributes -filetype=obj -o %t.o2// RUN: llvm-mc %s -triple=armv7a-linux-gnueabihf -arm-add-build-attributes -filetype=obj -o %t.o
3// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s3// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
44
deps/lld/test/ELF/arm-tls-le32.s+6-6
...@@ -69,9 +69,9 @@ x:...@@ -69,9 +69,9 @@ x:
6969
70// CHECK: Disassembly of section .text:70// CHECK: Disassembly of section .text:
71// CHECK-NEXT: _start:71// CHECK-NEXT: _start:
72// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)72// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20)
73// CHECK-NEXT: 11000: 08 00 00 0073// CHECK-NEXT: 11000: 20 00 00 00
74// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)74// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28)
75// CHECK-NEXT: 11004: 10 00 00 0075// CHECK-NEXT: 11004: 28 00 00 00
76// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)76// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24)
77// CHECK-NEXT: 11008: 0c 00 00 0077// CHECK-NEXT: 11008: 24 00 00 00
deps/lld/test/ELF/arm-tls-norelax-ie-le.s+2-2
...@@ -37,5 +37,5 @@ x2:...@@ -37,5 +37,5 @@ x2:
37 .type x2, %object37 .type x2, %object
3838
39// CHECK: Contents of section .got:39// CHECK: Contents of section .got:
40// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 840// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
41// CHECK-NEXT: 13064 08000000 0c00000041// CHECK-NEXT: 13064 20000000 24000000
deps/lld/test/ELF/arm-v4bx.test created+40
...@@ -0,0 +1,40 @@
1# REQUIRES: arm
2# RUN: yaml2obj %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readelf -sections %t | FileCheck %s
5# RUN: ld.lld -shared %t.o -o %t
6# RUN: llvm-readelf -sections %t | FileCheck %s
7
8# CHECK: .text
9
10--- !ELF
11FileHeader:
12 Class: ELFCLASS32
13 Data: ELFDATA2LSB
14 Type: ET_REL
15 Machine: EM_ARM
16 Flags: [ EF_ARM_EABI_VER5 ]
17Sections:
18 - Name: .text
19 Type: SHT_PROGBITS
20 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
21 AddressAlign: 0x0000000000000004
22 Content: 1EFF2F01
23 - Name: .rel.text
24 Type: SHT_REL
25 Link: .symtab
26 AddressAlign: 0x0000000000000004
27 Info: .text
28 Relocations:
29 - Offset: 0x0000000000000000
30 Symbol: ''
31 Type: R_ARM_V4BX
32Symbols:
33 Global:
34 - Name: _start
35 Section: .text
36 Local:
37 - Name: .text
38 Type: STT_SECTION
39 Section: .text
40DynamicSymbols:
deps/lld/test/ELF/arm-v5-reloc-error.s created+31
...@@ -0,0 +1,31 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t
3// RUN: echo "SECTIONS { \
4// RUN: . = SIZEOF_HEADERS; \
5// RUN: .text_low : { *(.text_low) *(.text_low2) } \
6// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
7// RUN: } " > %t.script
8// RUN: not ld.lld --script %t.script %t -o %t2 2>&1 | FileCheck %s
9
10// CHECK: error: relocation R_ARM_THM_JUMP24 to far not supported for Armv5 or Armv6 targets
11
12// Lie about our build attributes. Our triple is armv7a-linux-gnueabi but
13// we are claiming to be Armv5. This can also happen with llvm-mc when we
14// don't have any .eabi_attribute directives in the file or the
15// --arm-add-build-attributes command line isn't used to add them from the
16// triple.
17 .eabi_attribute 6, 5 // Tag_cpu_arch 5 = v5TEJ
18 .thumb
19 .syntax unified
20 .section .text_low, "ax", %progbits
21 .thumb
22 .globl _start
23 .type _start, %function
24_start:
25 b.w far // Will produce relocation not supported in Armv5.
26
27 .section .text_high, "ax", %progbits
28 .globl far
29 .type far, %function
30far:
31 bx lr
deps/lld/test/ELF/as-needed-in-regular.s created+24
...@@ -0,0 +1,24 @@
1# REQUIRES: x86
2
3# RUN: echo '.globl a; .type a, @function; .type a, @function; a: ret' | \
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
5# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
8# RUN: ld.lld %t.o --as-needed %ta.so -o %t
9# RUN: llvm-readelf -d %t | FileCheck %s
10# RUN: ld.lld %t.o --as-needed %ta.so --gc-sections -o %t
11# RUN: llvm-readelf -d %t | FileCheck %s
12
13# The order of %ta.so and %t.o does not matter.
14
15# RUN: ld.lld --as-needed %ta.so %t.o -o %t
16# RUN: llvm-readelf -d %t | FileCheck %s
17# RUN: ld.lld --as-needed %ta.so %t.o --gc-sections -o %t
18# RUN: llvm-readelf -d %t | FileCheck %s
19
20# CHECK: a.so
21
22.global _start
23_start:
24 jmp a@PLT
deps/lld/test/ELF/as-needed-not-in-regular.s created+32
...@@ -0,0 +1,32 @@
1# REQUIRES: x86
2
3# RUN: echo '.globl a1, a2; .type a1, @function; .type a2, @function; a1: a2: ret' | \
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
5# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
6
7# RUN: echo '.globl b; .type b, @function; b: jmp a1@PLT' | \
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tb.o
9# RUN: ld.lld %tb.o %ta.so --shared --soname=b.so -o %tb.so
10
11# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
12# RUN: ld.lld %t.o %tb.so --as-needed %ta.so -o %t
13# RUN: llvm-readelf -d %t | FileCheck %s
14
15# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --gc-sections -o %t
16# RUN: llvm-readelf -d %t | FileCheck %s
17
18# The symbol a1 (defined in a.so) is not referenced by a regular object,
19# the reference to a2 is weak, don't add a DT_NEEDED entry for a.so.
20# CHECK-NOT: a.so
21
22# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --no-as-needed %ta.so -o %t
23# RUN: llvm-readelf -d %t | FileCheck %s -check-prefix=NEEDED
24
25# a.so is needed because one of its occurrences is needed.
26# NEEDED: a.so
27
28.global _start
29.weak a2
30_start:
31 jmp b@PLT
32 jmp a2
deps/lld/test/ELF/as-needed-weak.s+1-1
...@@ -12,7 +12,7 @@...@@ -12,7 +12,7 @@
1212
13# CHECK: Symbol table of .hash for image:13# CHECK: Symbol table of .hash for image:
14# CHECK-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name14# CHECK-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
15# CHECK-NEXT: 1 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo@15# CHECK-NEXT: 1 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo
1616
17.globl _start17.globl _start
18.weak foo18.weak foo
deps/lld/test/ELF/bad-reloc-target.test created+29
...@@ -0,0 +1,29 @@
1# RUN: yaml2obj %s -o %t1.o
2# RUN: not ld.lld %t1.o -o %t1 2>&1 | FileCheck %s
3# CHECK: error: {{.*}}.o: unsupported relocation reference
4
5# RUN: yaml2obj %S/Inputs/bad-reloc-target.test -o %t2.o
6# RUN: not ld.lld %t2.o -o %t2 2>&1 | FileCheck %s --check-prefix=ERR2
7# ERR2: error: {{.*}}.o: invalid relocated section index: 99
8
9--- !ELF
10FileHeader:
11 Class: ELFCLASS64
12 Data: ELFDATA2LSB
13 Type: ET_REL
14 Machine: EM_X86_64
15Sections:
16 - Name: .text
17 Type: SHT_PROGBITS
18 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
19 - Name: .rela.text
20 Type: SHT_RELA
21 Link: .symtab
22 Info: 0
23 Relocations:
24 - Offset: 0x0000000000000000
25 Symbol: foo
26 Type: R_X86_64_64
27Symbols:
28 Global:
29 - Name: foo
\ No newline at end of file
deps/lld/test/ELF/basic-aarch64.s+8-8
...@@ -59,7 +59,7 @@ _start:...@@ -59,7 +59,7 @@ _start:
59# CHECK-NEXT: SHF_ALLOC (0x2)59# CHECK-NEXT: SHF_ALLOC (0x2)
60# CHECK-NEXT: SHF_EXECINSTR (0x4)60# CHECK-NEXT: SHF_EXECINSTR (0x4)
61# CHECK-NEXT: ]61# CHECK-NEXT: ]
62# CHECK-NEXT: Address: 0x2000062# CHECK-NEXT: Address: 0x210000
63# CHECK-NEXT: Offset: 0x1000063# CHECK-NEXT: Offset: 0x10000
64# CHECK-NEXT: Size: 1264# CHECK-NEXT: Size: 12
65# CHECK-NEXT: Link: 065# CHECK-NEXT: Link: 0
...@@ -138,7 +138,7 @@ _start:...@@ -138,7 +138,7 @@ _start:
138# CHECK-NEXT: }138# CHECK-NEXT: }
139# CHECK-NEXT: Symbol {139# CHECK-NEXT: Symbol {
140# CHECK-NEXT: Name: $x.0140# CHECK-NEXT: Name: $x.0
141# CHECK-NEXT: Value: 0x20000141# CHECK-NEXT: Value: 0x210000
142# CHECK-NEXT: Size: 0142# CHECK-NEXT: Size: 0
143# CHECK-NEXT: Binding: Local (0x0)143# CHECK-NEXT: Binding: Local (0x0)
144# CHECK-NEXT: Type: None (0x0)144# CHECK-NEXT: Type: None (0x0)
...@@ -159,8 +159,8 @@ _start:...@@ -159,8 +159,8 @@ _start:
159# CHECK-NEXT: ProgramHeader {159# CHECK-NEXT: ProgramHeader {
160# CHECK-NEXT: Type: PT_PHDR (0x6)160# CHECK-NEXT: Type: PT_PHDR (0x6)
161# CHECK-NEXT: Offset: 0x40161# CHECK-NEXT: Offset: 0x40
162# CHECK-NEXT: VirtualAddress: 0x10040162# CHECK-NEXT: VirtualAddress: 0x200040
163# CHECK-NEXT: PhysicalAddress: 0x10040163# CHECK-NEXT: PhysicalAddress: 0x200040
164# CHECK-NEXT: FileSize: 224164# CHECK-NEXT: FileSize: 224
165# CHECK-NEXT: MemSize: 224165# CHECK-NEXT: MemSize: 224
166# CHECK-NEXT: Flags [ (0x4)166# CHECK-NEXT: Flags [ (0x4)
...@@ -171,8 +171,8 @@ _start:...@@ -171,8 +171,8 @@ _start:
171# CHECK-NEXT: ProgramHeader {171# CHECK-NEXT: ProgramHeader {
172# CHECK-NEXT: Type: PT_LOAD (0x1)172# CHECK-NEXT: Type: PT_LOAD (0x1)
173# CHECK-NEXT: Offset: 0x0173# CHECK-NEXT: Offset: 0x0
174# CHECK-NEXT: VirtualAddress: 0x10000174# CHECK-NEXT: VirtualAddress: 0x200000
175# CHECK-NEXT: PhysicalAddress: 0x10000175# CHECK-NEXT: PhysicalAddress: 0x200000
176# CHECK-NEXT: FileSize: 288176# CHECK-NEXT: FileSize: 288
177# CHECK-NEXT: MemSize: 288177# CHECK-NEXT: MemSize: 288
178# CHECK-NEXT: Flags [178# CHECK-NEXT: Flags [
...@@ -183,8 +183,8 @@ _start:...@@ -183,8 +183,8 @@ _start:
183# CHECK-NEXT: ProgramHeader {183# CHECK-NEXT: ProgramHeader {
184# CHECK-NEXT: Type: PT_LOAD (0x1)184# CHECK-NEXT: Type: PT_LOAD (0x1)
185# CHECK-NEXT: Offset: 0x1000185# CHECK-NEXT: Offset: 0x1000
186# CHECK-NEXT: VirtualAddress: 0x20000186# CHECK-NEXT: VirtualAddress: 0x210000
187# CHECK-NEXT: PhysicalAddress: 0x20000187# CHECK-NEXT: PhysicalAddress: 0x210000
188# CHECK-NEXT: FileSize: 4096188# CHECK-NEXT: FileSize: 4096
189# CHECK-NEXT: MemSize: 4096189# CHECK-NEXT: MemSize: 4096
190# CHECK-NEXT: Flags [ (0x5)190# CHECK-NEXT: Flags [ (0x5)
deps/lld/test/ELF/basic-ppc64.s+34-17
...@@ -28,7 +28,7 @@...@@ -28,7 +28,7 @@
28// CHECK-NEXT: Version: 128// CHECK-NEXT: Version: 1
29// CHECK-NEXT: Entry: 0x1000029// CHECK-NEXT: Entry: 0x10000
30// CHECK-NEXT: ProgramHeaderOffset: 0x4030// CHECK-NEXT: ProgramHeaderOffset: 0x40
31// CHECK-NEXT: SectionHeaderOffset:31// CHECK-NEXT: SectionHeaderOffset: 0x200F8
32// CHECK-NEXT: Flags [ (0x2)32// CHECK-NEXT: Flags [ (0x2)
33// CHECK-NEXT: 0x233// CHECK-NEXT: 0x2
34// CHECK-NEXT: ]34// CHECK-NEXT: ]
...@@ -36,8 +36,8 @@...@@ -36,8 +36,8 @@
36// CHECK-NEXT: ProgramHeaderEntrySize: 5636// CHECK-NEXT: ProgramHeaderEntrySize: 56
37// CHECK-NEXT: ProgramHeaderCount: 737// CHECK-NEXT: ProgramHeaderCount: 7
38// CHECK-NEXT: SectionHeaderEntrySize: 6438// CHECK-NEXT: SectionHeaderEntrySize: 64
39// CHECK-NEXT: SectionHeaderCount: 1039// CHECK-NEXT: SectionHeaderCount: 11
40// CHECK-NEXT: StringTableSectionIndex: 840// CHECK-NEXT: StringTableSectionIndex: 9
41// CHECK-NEXT:}41// CHECK-NEXT:}
42// CHECK-NEXT:Sections [42// CHECK-NEXT:Sections [
43// CHECK-NEXT: Section {43// CHECK-NEXT: Section {
...@@ -156,7 +156,23 @@...@@ -156,7 +156,23 @@
156// CHECK-NEXT: }156// CHECK-NEXT: }
157// CHECK-NEXT: Section {157// CHECK-NEXT: Section {
158// CHECK-NEXT: Index: 6158// CHECK-NEXT: Index: 6
159// CHECK-NEXT: Name: .comment (38)159// CHECK-NEXT: Name: .branch_lt (38)
160// CHECK-NEXT: Type: SHT_NOBITS (0x8)
161// CHECK-NEXT: Flags [ (0x3)
162// CHECK-NEXT: SHF_ALLOC (0x2)
163// CHECK-NEXT: SHF_WRITE (0x1)
164// CHECK-NEXT: ]
165// CHECK-NEXT: Address: 0x30000
166// CHECK-NEXT: Offset: 0x20060
167// CHECK-NEXT: Size: 0
168// CHECK-NEXT: Link: 0
169// CHECK-NEXT: Info: 0
170// CHECK-NEXT: AddressAlignment: 8
171// CHECK-NEXT: EntrySize: 0
172// CHECK-NEXT: }
173// CHECK-NEXT: Section {
174// CHECK-NEXT: Index: 7
175// CHECK-NEXT: Name: .comment (49)
160// CHECK-NEXT: Type: SHT_PROGBITS (0x1)176// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
161// CHECK-NEXT: Flags [ (0x30)177// CHECK-NEXT: Flags [ (0x30)
162// CHECK-NEXT: SHF_MERGE (0x10)178// CHECK-NEXT: SHF_MERGE (0x10)
...@@ -174,15 +190,15 @@...@@ -174,15 +190,15 @@
174// CHECK-NEXT: )190// CHECK-NEXT: )
175// CHECK-NEXT: }191// CHECK-NEXT: }
176// CHECK-NEXT: Section {192// CHECK-NEXT: Section {
177// CHECK-NEXT: Index: 7193// CHECK-NEXT: Index: 8
178// CHECK-NEXT: Name: .symtab (47)194// CHECK-NEXT: Name: .symtab (58)
179// CHECK-NEXT: Type: SHT_SYMTAB (0x2)195// CHECK-NEXT: Type: SHT_SYMTAB (0x2)
180// CHECK-NEXT: Flags [ (0x0)196// CHECK-NEXT: Flags [ (0x0)
181// CHECK-NEXT: ]197// CHECK-NEXT: ]
182// CHECK-NEXT: Address: 0x0198// CHECK-NEXT: Address: 0x0
183// CHECK-NEXT: Offset: 0x20068199// CHECK-NEXT: Offset: 0x20068
184// CHECK-NEXT: Size: 48200// CHECK-NEXT: Size: 48
185// CHECK-NEXT: Link: 9201// CHECK-NEXT: Link: 10
186// CHECK-NEXT: Info: 2202// CHECK-NEXT: Info: 2
187// CHECK-NEXT: AddressAlignment: 8203// CHECK-NEXT: AddressAlignment: 8
188// CHECK-NEXT: EntrySize: 24204// CHECK-NEXT: EntrySize: 24
...@@ -193,14 +209,14 @@...@@ -193,14 +209,14 @@
193// CHECK-NEXT: )209// CHECK-NEXT: )
194// CHECK-NEXT: }210// CHECK-NEXT: }
195// CHECK-NEXT: Section {211// CHECK-NEXT: Section {
196// CHECK-NEXT: Index: 8212// CHECK-NEXT: Index: 9
197// CHECK-NEXT: Name: .shstrtab (55)213// CHECK-NEXT: Name: .shstrtab (66)
198// CHECK-NEXT: Type: SHT_STRTAB (0x3)214// CHECK-NEXT: Type: SHT_STRTAB (0x3)
199// CHECK-NEXT: Flags [ (0x0)215// CHECK-NEXT: Flags [ (0x0)
200// CHECK-NEXT: ]216// CHECK-NEXT: ]
201// CHECK-NEXT: Address: 0x0217// CHECK-NEXT: Address: 0x0
202// CHECK-NEXT: Offset: 0x20098218// CHECK-NEXT: Offset: 0x20098
203// CHECK-NEXT: Size: 73219// CHECK-NEXT: Size: 84
204// CHECK-NEXT: Link: 0220// CHECK-NEXT: Link: 0
205// CHECK-NEXT: Info: 0221// CHECK-NEXT: Info: 0
206// CHECK-NEXT: AddressAlignment: 1222// CHECK-NEXT: AddressAlignment: 1
...@@ -208,19 +224,20 @@...@@ -208,19 +224,20 @@
208// CHECK-NEXT: SectionData (224// CHECK-NEXT: SectionData (
209// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|225// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|
210// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|226// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|
211// CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..|227// CHECK-NEXT: 0020: 6E616D69 63002E62 72616E63 685F6C74 |namic..branch_lt|
212// CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab|228// CHECK-NEXT: 0030: 002E636F 6D6D656E 74002E73 796D7461 |..comment..symta|
213// CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.|229// CHECK-NEXT: 0040: 62002E73 68737472 74616200 2E737472 |b..shstrtab..str|
230// CHECK-NEXT: 0050: 74616200 |tab.|
214// CHECK-NEXT: )231// CHECK-NEXT: )
215// CHECK-NEXT: }232// CHECK-NEXT: }
216// CHECK-NEXT: Section {233// CHECK-NEXT: Section {
217// CHECK-NEXT: Index: 9234// CHECK-NEXT: Index: 10
218// CHECK-NEXT: Name: .strtab (65)235// CHECK-NEXT: Name: .strtab (76)
219// CHECK-NEXT: Type: SHT_STRTAB (0x3)236// CHECK-NEXT: Type: SHT_STRTAB (0x3)
220// CHECK-NEXT: Flags [ (0x0)237// CHECK-NEXT: Flags [ (0x0)
221// CHECK-NEXT: ]238// CHECK-NEXT: ]
222// CHECK-NEXT: Address: 0x0239// CHECK-NEXT: Address: 0x0
223// CHECK-NEXT: Offset: 0x200E1240// CHECK-NEXT: Offset: 0x200EC
224// CHECK-NEXT: Size: 10241// CHECK-NEXT: Size: 10
225// CHECK-NEXT: Link: 0242// CHECK-NEXT: Link: 0
226// CHECK-NEXT: Info: 0243// CHECK-NEXT: Info: 0
...@@ -275,7 +292,7 @@...@@ -275,7 +292,7 @@
275// CHECK-NEXT: VirtualAddress: 0x20000292// CHECK-NEXT: VirtualAddress: 0x20000
276// CHECK-NEXT: PhysicalAddress: 0x20000293// CHECK-NEXT: PhysicalAddress: 0x20000
277// CHECK-NEXT: FileSize: 96294// CHECK-NEXT: FileSize: 96
278// CHECK-NEXT: MemSize: 96295// CHECK-NEXT: MemSize: 65536
279// CHECK-NEXT: Flags [ (0x6)296// CHECK-NEXT: Flags [ (0x6)
280// CHECK-NEXT: PF_R (0x4)297// CHECK-NEXT: PF_R (0x4)
281// CHECK-NEXT: PF_W (0x2)298// CHECK-NEXT: PF_W (0x2)
deps/lld/test/ELF/basic32.s+8-8
...@@ -23,7 +23,7 @@ _start:...@@ -23,7 +23,7 @@ _start:
23# CHECK-NEXT: Type: Executable (0x2)23# CHECK-NEXT: Type: Executable (0x2)
24# CHECK-NEXT: Machine: EM_386 (0x3)24# CHECK-NEXT: Machine: EM_386 (0x3)
25# CHECK-NEXT: Version: 125# CHECK-NEXT: Version: 1
26# CHECK-NEXT: Entry: 0x1100026# CHECK-NEXT: Entry: 0x401000
27# CHECK-NEXT: ProgramHeaderOffset: 0x3427# CHECK-NEXT: ProgramHeaderOffset: 0x34
28# CHECK-NEXT: SectionHeaderOffset: 0x205C28# CHECK-NEXT: SectionHeaderOffset: 0x205C
29# CHECK-NEXT: Flags [ (0x0)29# CHECK-NEXT: Flags [ (0x0)
...@@ -58,7 +58,7 @@ _start:...@@ -58,7 +58,7 @@ _start:
58# CHECK-NEXT: SHF_ALLOC (0x2)58# CHECK-NEXT: SHF_ALLOC (0x2)
59# CHECK-NEXT: SHF_EXECINSTR (0x4)59# CHECK-NEXT: SHF_EXECINSTR (0x4)
60# CHECK-NEXT: ]60# CHECK-NEXT: ]
61# CHECK-NEXT: Address: 0x1100061# CHECK-NEXT: Address: 0x401000
62# CHECK-NEXT: Offset: 0x100062# CHECK-NEXT: Offset: 0x1000
63# CHECK-NEXT: Size: 1263# CHECK-NEXT: Size: 12
64# CHECK-NEXT: Link: 064# CHECK-NEXT: Link: 0
...@@ -129,8 +129,8 @@ _start:...@@ -129,8 +129,8 @@ _start:
129# CHECK-NEXT: ProgramHeader {129# CHECK-NEXT: ProgramHeader {
130# CHECK-NEXT: Type: PT_PHDR (0x6)130# CHECK-NEXT: Type: PT_PHDR (0x6)
131# CHECK-NEXT: Offset: 0x34131# CHECK-NEXT: Offset: 0x34
132# CHECK-NEXT: VirtualAddress: 0x10034132# CHECK-NEXT: VirtualAddress: 0x400034
133# CHECK-NEXT: PhysicalAddress: 0x10034133# CHECK-NEXT: PhysicalAddress: 0x400034
134# CHECK-NEXT: FileSize: 128134# CHECK-NEXT: FileSize: 128
135# CHECK-NEXT: MemSize: 128135# CHECK-NEXT: MemSize: 128
136# CHECK-NEXT: Flags [ (0x4)136# CHECK-NEXT: Flags [ (0x4)
...@@ -141,8 +141,8 @@ _start:...@@ -141,8 +141,8 @@ _start:
141# CHECK-NEXT: ProgramHeader {141# CHECK-NEXT: ProgramHeader {
142# CHECK-NEXT: Type: PT_LOAD (0x1)142# CHECK-NEXT: Type: PT_LOAD (0x1)
143# CHECK-NEXT: Offset: 0x0143# CHECK-NEXT: Offset: 0x0
144# CHECK-NEXT: VirtualAddress: 0x10000144# CHECK-NEXT: VirtualAddress: 0x400000
145# CHECK-NEXT: PhysicalAddress: 0x10000145# CHECK-NEXT: PhysicalAddress: 0x400000
146# CHECK-NEXT: FileSize: 180146# CHECK-NEXT: FileSize: 180
147# CHECK-NEXT: MemSize: 180147# CHECK-NEXT: MemSize: 180
148# CHECK-NEXT: Flags [148# CHECK-NEXT: Flags [
...@@ -153,8 +153,8 @@ _start:...@@ -153,8 +153,8 @@ _start:
153# CHECK-NEXT: ProgramHeader {153# CHECK-NEXT: ProgramHeader {
154# CHECK-NEXT: Type: PT_LOAD (0x1)154# CHECK-NEXT: Type: PT_LOAD (0x1)
155# CHECK-NEXT: Offset: 0x1000155# CHECK-NEXT: Offset: 0x1000
156# CHECK-NEXT: VirtualAddress: 0x11000156# CHECK-NEXT: VirtualAddress: 0x401000
157# CHECK-NEXT: PhysicalAddress: 0x11000157# CHECK-NEXT: PhysicalAddress: 0x401000
158# CHECK-NEXT: FileSize: 4096158# CHECK-NEXT: FileSize: 4096
159# CHECK-NEXT: MemSize: 4096159# CHECK-NEXT: MemSize: 4096
160# CHECK-NEXT: Flags [ (0x5)160# CHECK-NEXT: Flags [ (0x5)
deps/lld/test/ELF/basic64be.s+42-23
...@@ -23,7 +23,7 @@...@@ -23,7 +23,7 @@
23# CHECK-NEXT: Version: 123# CHECK-NEXT: Version: 1
24# CHECK-NEXT: Entry: 0x1001000024# CHECK-NEXT: Entry: 0x10010000
25# CHECK-NEXT: ProgramHeaderOffset: 0x4025# CHECK-NEXT: ProgramHeaderOffset: 0x40
26# CHECK-NEXT: SectionHeaderOffset: 0x1105026# CHECK-NEXT: SectionHeaderOffset: 0x20058
27# CHECK-NEXT: Flags [ (0x2)27# CHECK-NEXT: Flags [ (0x2)
28# CHECK-NEXT: 0x228# CHECK-NEXT: 0x2
29# CHECK-NEXT: ]29# CHECK-NEXT: ]
...@@ -31,8 +31,8 @@...@@ -31,8 +31,8 @@
31# CHECK-NEXT: ProgramHeaderEntrySize: 5631# CHECK-NEXT: ProgramHeaderEntrySize: 56
32# CHECK-NEXT: ProgramHeaderCount: 432# CHECK-NEXT: ProgramHeaderCount: 4
33# CHECK-NEXT: SectionHeaderEntrySize: 6433# CHECK-NEXT: SectionHeaderEntrySize: 64
34# CHECK-NEXT: SectionHeaderCount: 634# CHECK-NEXT: SectionHeaderCount: 7
35# CHECK-NEXT: StringTableSectionIndex: 435# CHECK-NEXT: StringTableSectionIndex: 5
36# CHECK-NEXT: }36# CHECK-NEXT: }
37# CHECK-NEXT: Sections [37# CHECK-NEXT: Sections [
38# CHECK-NEXT: Section {38# CHECK-NEXT: Section {
...@@ -72,14 +72,32 @@...@@ -72,14 +72,32 @@
72# CHECK-NEXT: }72# CHECK-NEXT: }
73# CHECK-NEXT: Section {73# CHECK-NEXT: Section {
74# CHECK-NEXT: Index: 274# CHECK-NEXT: Index: 2
75# CHECK-NEXT: Name: .comment (7)75# CHECK-NEXT: Name: .branch_lt (7)
76# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
77# CHECK-NEXT: Flags [ (0x3)
78# CHECK-NEXT: SHF_ALLOC (0x2)
79# CHECK-NEXT: SHF_WRITE (0x1)
80# CHECK-NEXT: ]
81# CHECK-NEXT: Address: 0x10020000
82# CHECK-NEXT: Offset: 0x20000
83# CHECK-NEXT: Size: 0
84# CHECK-NEXT: Link: 0
85# CHECK-NEXT: Info: 0
86# CHECK-NEXT: AddressAlignment: 8
87# CHECK-NEXT: EntrySize: 0
88# CHECK-NEXT: SectionData (
89# CHECK-NEXT: )
90# CHECK-NEXT: }
91# CHECK-NEXT: Section {
92# CHECK-NEXT: Index: 3
93# CHECK-NEXT: Name: .comment (18)
76# CHECK-NEXT: Type: SHT_PROGBITS (0x1)94# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
77# CHECK-NEXT: Flags [ (0x30)95# CHECK-NEXT: Flags [ (0x30)
78# CHECK-NEXT: SHF_MERGE (0x10)96# CHECK-NEXT: SHF_MERGE (0x10)
79# CHECK-NEXT: SHF_STRINGS (0x20)97# CHECK-NEXT: SHF_STRINGS (0x20)
80# CHECK-NEXT: ]98# CHECK-NEXT: ]
81# CHECK-NEXT: Address: 0x099# CHECK-NEXT: Address: 0x0
82# CHECK-NEXT: Offset: 0x11000100# CHECK-NEXT: Offset: 0x20000
83# CHECK-NEXT: Size: 8101# CHECK-NEXT: Size: 8
84# CHECK-NEXT: Link: 0102# CHECK-NEXT: Link: 0
85# CHECK-NEXT: Info: 0103# CHECK-NEXT: Info: 0
...@@ -90,15 +108,15 @@...@@ -90,15 +108,15 @@
90# CHECK-NEXT: )108# CHECK-NEXT: )
91# CHECK-NEXT: }109# CHECK-NEXT: }
92# CHECK-NEXT: Section {110# CHECK-NEXT: Section {
93# CHECK-NEXT: Index: 3111# CHECK-NEXT: Index: 4
94# CHECK-NEXT: Name: .symtab (16)112# CHECK-NEXT: Name: .symtab (27)
95# CHECK-NEXT: Type: SHT_SYMTAB (0x2)113# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
96# CHECK-NEXT: Flags [ (0x0)114# CHECK-NEXT: Flags [ (0x0)
97# CHECK-NEXT: ]115# CHECK-NEXT: ]
98# CHECK-NEXT: Address: 0x0116# CHECK-NEXT: Address: 0x0
99# CHECK-NEXT: Offset: 0x11008117# CHECK-NEXT: Offset: 0x20008
100# CHECK-NEXT: Size: 24118# CHECK-NEXT: Size: 24
101# CHECK-NEXT: Link: 5119# CHECK-NEXT: Link: 6
102# CHECK-NEXT: Info: 1120# CHECK-NEXT: Info: 1
103# CHECK-NEXT: AddressAlignment: 8121# CHECK-NEXT: AddressAlignment: 8
104# CHECK-NEXT: EntrySize: 24122# CHECK-NEXT: EntrySize: 24
...@@ -108,32 +126,33 @@...@@ -108,32 +126,33 @@
108# CHECK-NEXT: )126# CHECK-NEXT: )
109# CHECK-NEXT: }127# CHECK-NEXT: }
110# CHECK-NEXT: Section {128# CHECK-NEXT: Section {
111# CHECK-NEXT: Index: 4129# CHECK-NEXT: Index: 5
112# CHECK-NEXT: Name: .shstrtab (24)130# CHECK-NEXT: Name: .shstrtab (35)
113# CHECK-NEXT: Type: SHT_STRTAB (0x3)131# CHECK-NEXT: Type: SHT_STRTAB (0x3)
114# CHECK-NEXT: Flags [ (0x0)132# CHECK-NEXT: Flags [ (0x0)
115# CHECK-NEXT: ]133# CHECK-NEXT: ]
116# CHECK-NEXT: Address: 0x0134# CHECK-NEXT: Address: 0x0
117# CHECK-NEXT: Offset: 0x11020135# CHECK-NEXT: Offset: 0x20020
118# CHECK-NEXT: Size: 42136# CHECK-NEXT: Size: 53
119# CHECK-NEXT: Link: 0137# CHECK-NEXT: Link: 0
120# CHECK-NEXT: Info: 0138# CHECK-NEXT: Info: 0
121# CHECK-NEXT: AddressAlignment: 1139# CHECK-NEXT: AddressAlignment: 1
122# CHECK-NEXT: EntrySize: 0140# CHECK-NEXT: EntrySize: 0
123# CHECK-NEXT: SectionData (141# CHECK-NEXT: SectionData (
124# CHECK-NEXT: 0000: 002E7465 7874002E 636F6D6D 656E7400 |..text..comment.|142# CHECK-NEXT: 0000: 002E7465 7874002E 6272616E 63685F6C |..text..branch_l|
125# CHECK-NEXT: 0010: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta|143# CHECK-NEXT: 0010: 74002E63 6F6D6D65 6E74002E 73796D74 |t..comment..symt|
126# CHECK-NEXT: 0020: 62002E73 74727461 6200 |b..strtab.|144# CHECK-NEXT: 0020: 6162002E 73687374 72746162 002E7374 |ab..shstrtab..st|
145# CHECK-NEXT: 0030: 72746162 00 |rtab.|
127# CHECK-NEXT: )146# CHECK-NEXT: )
128# CHECK-NEXT: }147# CHECK-NEXT: }
129# CHECK-NEXT: Section {148# CHECK-NEXT: Section {
130# CHECK-NEXT: Index: 5149# CHECK-NEXT: Index: 6
131# CHECK-NEXT: Name: .strtab (34)150# CHECK-NEXT: Name: .strtab (45)
132# CHECK-NEXT: Type: SHT_STRTAB (0x3)151# CHECK-NEXT: Type: SHT_STRTAB (0x3)
133# CHECK-NEXT: Flags [ (0x0)152# CHECK-NEXT: Flags [ (0x0)
134# CHECK-NEXT: ]153# CHECK-NEXT: ]
135# CHECK-NEXT: Address: 0x0154# CHECK-NEXT: Address: 0x0
136# CHECK-NEXT: Offset: 0x1104A155# CHECK-NEXT: Offset: 0x20055
137# CHECK-NEXT: Size: 1156# CHECK-NEXT: Size: 1
138# CHECK-NEXT: Link: 0157# CHECK-NEXT: Link: 0
139# CHECK-NEXT: Info: 0158# CHECK-NEXT: Info: 0
...@@ -150,8 +169,8 @@...@@ -150,8 +169,8 @@
150# CHECK-NEXT: Offset: 0x40169# CHECK-NEXT: Offset: 0x40
151# CHECK-NEXT: VirtualAddress: 0x10000040170# CHECK-NEXT: VirtualAddress: 0x10000040
152# CHECK-NEXT: PhysicalAddress: 0x10000040171# CHECK-NEXT: PhysicalAddress: 0x10000040
153# CHECK-NEXT: FileSize: 224172# CHECK-NEXT: FileSize: 280
154# CHECK-NEXT: MemSize: 224173# CHECK-NEXT: MemSize: 280
155# CHECK-NEXT: Flags [ (0x4)174# CHECK-NEXT: Flags [ (0x4)
156# CHECK-NEXT: PF_R (0x4)175# CHECK-NEXT: PF_R (0x4)
157# CHECK-NEXT: ]176# CHECK-NEXT: ]
...@@ -162,8 +181,8 @@...@@ -162,8 +181,8 @@
162# CHECK-NEXT: Offset: 0x0181# CHECK-NEXT: Offset: 0x0
163# CHECK-NEXT: VirtualAddress: 0x10000000182# CHECK-NEXT: VirtualAddress: 0x10000000
164# CHECK-NEXT: PhysicalAddress: 0x10000000183# CHECK-NEXT: PhysicalAddress: 0x10000000
165# CHECK-NEXT: FileSize: 288184# CHECK-NEXT: FileSize: 344
166# CHECK-NEXT: MemSize: 288185# CHECK-NEXT: MemSize: 344
167# CHECK-NEXT: Flags [ (0x4)186# CHECK-NEXT: Flags [ (0x4)
168# CHECK-NEXT: PF_R (0x4)187# CHECK-NEXT: PF_R (0x4)
169# CHECK-NEXT: ]188# CHECK-NEXT: ]
deps/lld/test/ELF/bsymbolic-undef.s+2-2
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
55
6# CHECK: DynamicSymbols [6# CHECK: DynamicSymbols [
7# CHECK-NEXT: Symbol {7# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @8# CHECK-NEXT: Name:
9# CHECK-NEXT: Value: 0x09# CHECK-NEXT: Value: 0x0
10# CHECK-NEXT: Size: 010# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local (0x0)11# CHECK-NEXT: Binding: Local (0x0)
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14# CHECK-NEXT: Section: Undefined (0x0)14# CHECK-NEXT: Section: Undefined (0x0)
15# CHECK-NEXT: }15# CHECK-NEXT: }
16# CHECK-NEXT: Symbol {16# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: undef@17# CHECK-NEXT: Name: undef
18# CHECK-NEXT: Value: 0x018# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 019# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Global (0x1)20# CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/cgprofile-obj.s created+44
...@@ -0,0 +1,44 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld -e A %t.o -o %t
5# RUN: llvm-nm --no-sort %t | FileCheck %s
6# RUN: ld.lld --no-call-graph-profile-sort -e A %t.o -o %t
7# RUN: llvm-nm --no-sort %t | FileCheck %s --check-prefix=NO-CG
8
9 .section .text.D,"ax",@progbits
10D:
11 retq
12
13 .section .text.C,"ax",@progbits
14 .globl C
15C:
16 retq
17
18 .section .text.B,"ax",@progbits
19 .globl B
20B:
21 retq
22
23 .section .text.A,"ax",@progbits
24 .globl A
25A:
26Aa:
27 retq
28
29 .cg_profile A, B, 10
30 .cg_profile A, B, 10
31 .cg_profile Aa, B, 80
32 .cg_profile A, C, 40
33 .cg_profile B, C, 30
34 .cg_profile C, D, 90
35
36# CHECK: 0000000000201003 t D
37# CHECK: 0000000000201000 T A
38# CHECK: 0000000000201001 T B
39# CHECK: 0000000000201002 T C
40
41# NO-CG: 0000000000201000 t D
42# NO-CG: 0000000000201003 T A
43# NO-CG: 0000000000201002 T B
44# NO-CG: 0000000000201001 T C
deps/lld/test/ELF/cgprofile-shared-warn.s created+21
...@@ -0,0 +1,21 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld --shared %t.o -o /dev/null 2>&1 | count 0
5# RUN: ld.lld -e A --unresolved-symbols=ignore-all %t.o -o /dev/null 2>&1 | count 0
6
7# RUN: echo '.globl B; B: ret' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o
8# RUN: ld.lld --shared %t1.o -o %t1.so
9# RUN: ld.lld -e A %t.o %t1.so -o /dev/null 2>&1 | count 0
10
11# RUN: ld.lld --gc-sections %t.o %t1.so -o /dev/null 2>&1 | count 0
12.globl _start
13_start:
14 ret
15
16.section .text.A,"ax",@progbits
17.globl A
18A:
19 callq B
20
21.cg_profile A, B, 10
deps/lld/test/ELF/cgprofile-txt2.s created+38
...@@ -0,0 +1,38 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: echo "A B 5" > %t.call_graph
5# RUN: echo "B C 50" >> %t.call_graph
6# RUN: echo "C D 40" >> %t.call_graph
7# RUN: echo "D B 10" >> %t.call_graph
8# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
9# RUN: llvm-readobj -symbols %t2 | FileCheck %s
10
11# CHECK: Name: A
12# CHECK-NEXT: Value: 0x201003
13# CHECK: Name: B
14# CHECK-NEXT: Value: 0x201000
15# CHECK: Name: C
16# CHECK-NEXT: Value: 0x201001
17# CHECK: Name: D
18# CHECK-NEXT: Value: 0x201002
19
20.section .text.A,"ax",@progbits
21.globl A
22A:
23 nop
24
25.section .text.B,"ax",@progbits
26.globl B
27B:
28 nop
29
30.section .text.C,"ax",@progbits
31.globl C
32C:
33 nop
34
35.section .text.D,"ax",@progbits
36.globl D
37D:
38 nop
deps/lld/test/ELF/comdat-linkonce.s+6-1
...@@ -4,7 +4,12 @@...@@ -4,7 +4,12 @@
4// RUN: ld.lld -shared %t.o %t2.o -o %t4// RUN: ld.lld -shared %t.o %t2.o -o %t
5// RUN: ld.lld -shared %t2.o %t.o -o %t5// RUN: ld.lld -shared %t2.o %t.o -o %t
66
7.section .gnu.linkonce.t.zed7.section .gnu.linkonce.t.__x86.get_pc_thunk.bx
8.globl abc8.globl abc
9abc:9abc:
10nop10nop
11
12.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
13.globl def
14def:
15nop
deps/lld/test/ELF/common-gc2.s+2-2
...@@ -3,8 +3,8 @@...@@ -3,8 +3,8 @@
3# RUN: ld.lld -gc-sections -export-dynamic %t -o %t13# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
4# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s4# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
55
6# CHECK: Name: bar@6# CHECK: Name: bar
7# CHECK: Name: foo@7# CHECK: Name: foo
88
9.comm foo,4,49.comm foo,4,4
10.comm bar,4,410.comm bar,4,4
deps/lld/test/ELF/compressed-debug-input-err.s+2-2
...@@ -3,8 +3,8 @@...@@ -3,8 +3,8 @@
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s4# RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
55
6## Check we are able to report zlib decompressor errors.6## Check we are able to report zlib uncompress errors.
7# CHECK: error: {{.*}}.o:(.zdebug_str): decompress failed: zlib error: Z_DATA_ERROR7# CHECK: error: {{.*}}.o:(.debug_str): uncompress failed: zlib error: Z_DATA_ERROR
88
9.section .zdebug_str,"MS",@progbits,19.section .zdebug_str,"MS",@progbits,1
10 .ascii "ZLIB"10 .ascii "ZLIB"
deps/lld/test/ELF/conflict.s+1
...@@ -26,6 +26,7 @@...@@ -26,6 +26,7 @@
26# RUN: FileCheck -check-prefix=DEMANGLE %s26# RUN: FileCheck -check-prefix=DEMANGLE %s
2727
28# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o28# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o
29# RUN: rm -f %t3.a
29# RUN: llvm-ar rcs %t3.a %t2.o30# RUN: llvm-ar rcs %t3.a %t2.o
30# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s31# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s
3132
deps/lld/test/ELF/copy-rel-tls.s created+15
...@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-tls.s -o %t1.o
4// RUN: ld.lld %t1.o -shared -soname t1.so -o %t1.so
5// RUN: ld.lld %t.o %t1.so -o %t
6// RUN: llvm-nm %t1.so | FileCheck %s
7// RUN: llvm-nm %t | FileCheck --check-prefix=TLS %s
8// foo and tfoo have the same st_value but we should not copy tfoo.
9// CHECK: 2000 B foo
10// CHECK: 2000 B tfoo
11// TLS-NOT: tfoo
12
13.global _start
14_start:
15 leaq foo, %rax
deps/lld/test/ELF/debug-line-str.s created+136
...@@ -0,0 +1,136 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -dwarf-version=5 %s -o %t.o
3# RUN: not ld.lld %t.o -o %t1 2>&1 | FileCheck %s
4
5# Check we do not crash and able to report the source location.
6
7# CHECK: error: undefined symbol: foo()
8# CHECK-NEXT: >>> referenced by test.cpp:3
9# CHECK-NEXT: >>> {{.*}}.o:(.text+0x1)
10
11# The code below is the reduced version of the output
12# from the following invocation and source:
13#
14# // test.cpp:
15# int foo();
16# int main() {
17# return foo();
18# }
19#
20# clang -gdwarf-5 test.cpp -o test.s -S
21# clang version 8.0.0 (trunk 343487)
22
23.text
24.file "test.cpp"
25.globl main
26.type main,@function
27main:
28.Lfunc_begin0:
29 .file 0 "/home/path" "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
30 .file 1 "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
31 .loc 1 3 10 prologue_end
32 jmp _Z3foov
33.Lfunc_end0:
34
35.Lstr_offsets_base0:
36.section .debug_str,"MS",@progbits,1
37 .asciz "stub"
38
39.section .debug_str_offsets,"",@progbits
40 .long 0
41
42.section .debug_abbrev,"",@progbits
43 .byte 1 # Abbreviation Code
44 .byte 17 # DW_TAG_compile_unit
45 .byte 0 # DW_CHILDREN_yes
46 .byte 37 # DW_AT_producer
47 .byte 37 # DW_FORM_strx1
48 .byte 19 # DW_AT_language
49 .byte 5 # DW_FORM_data2
50 .byte 3 # DW_AT_name
51 .byte 37 # DW_FORM_strx1
52 .byte 114 # DW_AT_str_offsets_base
53 .byte 23 # DW_FORM_sec_offset
54 .byte 16 # DW_AT_stmt_list
55 .byte 23 # DW_FORM_sec_offset
56 .byte 27 # DW_AT_comp_dir
57 .byte 37 # DW_FORM_strx1
58 .byte 17 # DW_AT_low_pc
59 .byte 1 # DW_FORM_addr
60 .byte 18 # DW_AT_high_pc
61 .byte 6 # DW_FORM_data4
62 .byte 0 # EOM(1)
63 .byte 0 # EOM(2)
64
65 .byte 2 # Abbreviation Code
66 .byte 46 # DW_TAG_subprogram
67 .byte 0 # DW_CHILDREN_no
68 .byte 17 # DW_AT_low_pc
69 .byte 1 # DW_FORM_addr
70 .byte 18 # DW_AT_high_pc
71 .byte 6 # DW_FORM_data4
72 .byte 64 # DW_AT_frame_base
73 .byte 24 # DW_FORM_exprloc
74 .byte 3 # DW_AT_name
75 .byte 37 # DW_FORM_strx1
76 .byte 58 # DW_AT_decl_file
77 .byte 11 # DW_FORM_data1
78 .byte 59 # DW_AT_decl_line
79 .byte 11 # DW_FORM_data1
80 .byte 73 # DW_AT_type
81 .byte 19 # DW_FORM_ref4
82 .byte 63 # DW_AT_external
83 .byte 25 # DW_FORM_flag_present
84 .byte 0 # EOM(1)
85 .byte 0 # EOM(2)
86
87 .byte 3 # Abbreviation Code
88 .byte 36 # DW_TAG_base_type
89 .byte 0 # DW_CHILDREN_no
90 .byte 3 # DW_AT_name
91 .byte 37 # DW_FORM_strx1
92 .byte 62 # DW_AT_encoding
93 .byte 11 # DW_FORM_data1
94 .byte 11 # DW_AT_byte_size
95 .byte 11 # DW_FORM_data1
96 .byte 0 # EOM(1)
97 .byte 0 # EOM(2)
98 .byte 0 # EOM(3)
99
100.section .debug_info,"",@progbits
101.Lcu_begin0:
102 .long 61 # Length of Unit
103 .short 5 # DWARF version number
104 .byte 1 # DWARF Unit Type
105 .byte 8 # Address Size (in bytes)
106 .long .debug_abbrev # Offset Into Abbrev. Section
107
108 .byte 1 # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit
109 .byte 0 # DW_AT_producer
110 .short 0 # DW_AT_language
111 .byte 0 # DW_AT_name
112 .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
113 .long .Lline_table_start0 # DW_AT_stmt_list
114 .byte 0 # DW_AT_comp_dir
115 .quad .Lfunc_begin0 # DW_AT_low_pc
116 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
117
118 .byte 2 # Abbrev [2] 0x26:0x16 DW_TAG_subprogram
119 .quad .Lfunc_begin0 # DW_AT_low_pc
120 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
121 .byte 1 # DW_AT_frame_base
122 .byte 87
123 .byte 0 # DW_AT_name
124 .byte 1 # DW_AT_decl_file
125 .byte 2 # DW_AT_decl_line
126 .long 60 # DW_AT_type
127 # DW_AT_external
128
129 .byte 3 # Abbrev [3] 0x3c:0x4 DW_TAG_base_type
130 .byte 0 # DW_AT_name
131 .byte 5 # DW_AT_encoding
132 .byte 4 # DW_AT_byte_size
133 .byte 0 # End Of Children Mark
134
135.section .debug_line,"",@progbits
136.Lline_table_start0:
deps/lld/test/ELF/debug-relocation-none.test created+58
...@@ -0,0 +1,58 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
4
5## Previously we would report an error saying the relocation in .debug_info
6## has an unsupported target.
7## Check we do not report debug information parsing errors when relocation
8## used is of type R_*_NONE, what actually means it should be ignored.
9
10# CHECK-NOT: error
11# CHECK: error: undefined symbol: bar
12# CHECK-NOT: error
13
14--- !ELF
15FileHeader:
16 Class: ELFCLASS64
17 Data: ELFDATA2LSB
18 Type: ET_REL
19 Machine: EM_X86_64
20Sections:
21 - Name: .text
22 Type: SHT_PROGBITS
23 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
24 Content: '0000000000000000'
25 - Name: .rela.text
26 Type: SHT_RELA
27 AddressAlign: 8
28 Link: .symtab
29 Info: .text
30 Relocations:
31 - Offset: 0x0000000000000000
32 Symbol: bar
33 Type: R_X86_64_64
34 - Name: .debug_line
35 Type: SHT_PROGBITS
36 Content: 3300000002001C0000000101FB0E0D000101010100000001000001006162632E7300000000000009020000000000000000140208000101
37 - Name: .rela.debug_line
38 AddressAlign: 8
39 Type: SHT_RELA
40 Link: .symtab
41 Info: .debug_line
42 Relocations:
43 - Offset: 0x0000000000000029
44 Type: R_X86_64_NONE
45 - Name: .debug_info
46 Type: SHT_PROGBITS
47 AddressAlign: 0x0000000000000001
48 Content: 0C000000040000000000080100000000
49 - Name: .debug_abbrev
50 Type: SHT_PROGBITS
51 AddressAlign: 0x0000000000000001
52 Content: '0111001017000000'
53
54Symbols:
55 Global:
56 - Name: _start
57 Section: .text
58 - Name: bar
deps/lld/test/ELF/defsym.s+17-2
...@@ -9,6 +9,12 @@...@@ -9,6 +9,12 @@
9# RUN: llvm-readobj -t -s %t2 | FileCheck %s9# RUN: llvm-readobj -t -s %t2 | FileCheck %s
10# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE10# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE
1111
12## Check we are reporting the error correctly and don't crash
13## when handling the second --defsym.
14# RUN: not ld.lld -o %t2 %t.o --defsym ERR+ \
15# --defsym foo2=foo1 2>&1 | FileCheck %s --check-prefix=ERR
16# ERR: error: -defsym: syntax error: ERR+
17
12# CHECK: Symbol {18# CHECK: Symbol {
13# CHECK: Name: foo119# CHECK: Name: foo1
14# CHECK-NEXT: Value: 0x12320# CHECK-NEXT: Value: 0x123
...@@ -68,8 +74,17 @@...@@ -68,8 +74,17 @@
68# EXPR-NEXT: Section: Absolute74# EXPR-NEXT: Section: Absolute
69# EXPR-NEXT: }75# EXPR-NEXT: }
7076
71# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR77# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR1
72# ERR: error: -defsym:1: symbol not found: und78# ERR1: error: -defsym:1: symbol not found: und
79
80# RUN: not ld.lld -o %t %t.o --defsym=xxx=yyy,zzz 2>&1 | FileCheck %s -check-prefix=ERR2
81# ERR2: -defsym:1: EOF expected, but got ,
82
83# RUN: not ld.lld -o %t %t.o --defsym=foo 2>&1 | FileCheck %s -check-prefix=ERR3
84# ERR3: error: -defsym: syntax error: foo
85
86# RUN: not ld.lld -o %t %t.o --defsym= 2>&1 | FileCheck %s -check-prefix=ERR4
87# ERR4: error: -defsym: syntax error:
7388
74.globl foo189.globl foo1
75 foo1 = 0x12390 foo1 = 0x123
deps/lld/test/ELF/dont-export-hidden.s+1-1
...@@ -19,7 +19,7 @@ foo:...@@ -19,7 +19,7 @@ foo:
1919
20// CHECK: DynamicSymbols [20// CHECK: DynamicSymbols [
21// CHECK-NEXT: Symbol {21// CHECK-NEXT: Symbol {
22// CHECK-NEXT: Name: @22// CHECK-NEXT: Name:
23// CHECK-NEXT: Value: 0x023// CHECK-NEXT: Value: 0x0
24// CHECK-NEXT: Size: 024// CHECK-NEXT: Size: 0
25// CHECK-NEXT: Binding: Local25// CHECK-NEXT: Binding: Local
deps/lld/test/ELF/driver-access.test+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1# REQUIRES: x86, shell1# REQUIRES: x86
2# Make sure that LLD works even if the current directory is not writable.2# Make sure that LLD works even if the current directory is not writable.
33
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
deps/lld/test/ELF/driver.test+3
...@@ -62,6 +62,9 @@...@@ -62,6 +62,9 @@
62# RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s62# RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s
63# ERR10: unknown -z value: foo63# ERR10: unknown -z value: foo
6464
65## Check we report "unknown -z value" error even with -v.
66# RUN: not ld.lld %t -z foo -v 2>&1 | FileCheck -check-prefix=ERR10 %s
67
65# RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s68# RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s
66# ERR11: unknown -z value: max-page-size69# ERR11: unknown -z value: max-page-size
6770
deps/lld/test/ELF/dt_flags.s+3-2
...@@ -3,7 +3,8 @@...@@ -3,7 +3,8 @@
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld -shared %t -o %t.so4# RUN: ld.lld -shared %t -o %t.so
55
6# RUN: ld.lld -z initfirst -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t16# RUN: ld.lld -z global -z initfirst -z interpose -z now -z nodefaultlib \
7# RUN: -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
7# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s8# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
89
9# RUN: ld.lld %t %t.so -o %t210# RUN: ld.lld %t %t.so -o %t2
...@@ -14,7 +15,7 @@...@@ -14,7 +15,7 @@
1415
15# FLAGS: DynamicSection [16# FLAGS: DynamicSection [
16# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW17# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
17# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE INITFIRST NOOPEN ORIGIN18# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL NODELETE INITFIRST NOOPEN ORIGIN INTERPOSE NODEFLIB
18# FLAGS: ]19# FLAGS: ]
1920
20# CHECK: DynamicSection [21# CHECK: DynamicSection [
deps/lld/test/ELF/dynamic-list-locals.s created+7
...@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "{ local: *; };" > %t.list
5# RUN: not ld.lld -dynamic-list %t.list -shared %t.o -o %t.so 2>&1 | FileCheck %s
6
7# CHECK: error: {{.*}}:1: "local:" scope not supported in --dynamic-list
deps/lld/test/ELF/dynamic-list-preempt.s+4-4
...@@ -16,7 +16,7 @@...@@ -16,7 +16,7 @@
1616
17# DYNSYMS: DynamicSymbols [17# DYNSYMS: DynamicSymbols [
18# DYNSYMS-NEXT: Symbol {18# DYNSYMS-NEXT: Symbol {
19# DYNSYMS-NEXT: Name: @ (0)19# DYNSYMS-NEXT: Name:
20# DYNSYMS-NEXT: Value: 0x020# DYNSYMS-NEXT: Value: 0x0
21# DYNSYMS-NEXT: Size: 021# DYNSYMS-NEXT: Size: 0
22# DYNSYMS-NEXT: Binding: Local22# DYNSYMS-NEXT: Binding: Local
...@@ -25,7 +25,7 @@...@@ -25,7 +25,7 @@
25# DYNSYMS-NEXT: Section: Undefined25# DYNSYMS-NEXT: Section: Undefined
26# DYNSYMS-NEXT: }26# DYNSYMS-NEXT: }
27# DYNSYMS-NEXT: Symbol {27# DYNSYMS-NEXT: Symbol {
28# DYNSYMS-NEXT: Name: bar@28# DYNSYMS-NEXT: Name: bar
29# DYNSYMS-NEXT: Value:29# DYNSYMS-NEXT: Value:
30# DYNSYMS-NEXT: Size:30# DYNSYMS-NEXT: Size:
31# DYNSYMS-NEXT: Binding: Global31# DYNSYMS-NEXT: Binding: Global
...@@ -34,7 +34,7 @@...@@ -34,7 +34,7 @@
34# DYNSYMS-NEXT: Section:34# DYNSYMS-NEXT: Section:
35# DYNSYMS-NEXT: }35# DYNSYMS-NEXT: }
36# DYNSYMS-NEXT: Symbol {36# DYNSYMS-NEXT: Symbol {
37# DYNSYMS-NEXT: Name: ext@37# DYNSYMS-NEXT: Name: ext
38# DYNSYMS-NEXT: Value:38# DYNSYMS-NEXT: Value:
39# DYNSYMS-NEXT: Size:39# DYNSYMS-NEXT: Size:
40# DYNSYMS-NEXT: Binding: Global40# DYNSYMS-NEXT: Binding: Global
...@@ -43,7 +43,7 @@...@@ -43,7 +43,7 @@
43# DYNSYMS-NEXT: Section:43# DYNSYMS-NEXT: Section:
44# DYNSYMS-NEXT: }44# DYNSYMS-NEXT: }
45# DYNSYMS-NEXT: Symbol {45# DYNSYMS-NEXT: Symbol {
46# DYNSYMS-NEXT: Name: foo@46# DYNSYMS-NEXT: Name: foo
47# DYNSYMS-NEXT: Value:47# DYNSYMS-NEXT: Value:
48# DYNSYMS-NEXT: Size:48# DYNSYMS-NEXT: Size:
49# DYNSYMS-NEXT: Binding: Global49# DYNSYMS-NEXT: Binding: Global
deps/lld/test/ELF/dynamic-list-unexpected-end.s created+7
...@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "{ }; foo;" > %t.list
5# RUN: not ld.lld -dynamic-list %t.list -shared %t.o -o %t.so 2>&1 | FileCheck %s
6
7# CHECK: error: {{.*}}:1: EOF expected, but got foo
deps/lld/test/ELF/dynamic-list-wildcard.s+3-3
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
88
9# CHECK: DynamicSymbols [9# CHECK: DynamicSymbols [
10# CHECK-NEXT: Symbol {10# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name: @ (0)11# CHECK-NEXT: Name:
12# CHECK-NEXT: Value: 0x012# CHECK-NEXT: Value: 0x0
13# CHECK-NEXT: Size: 013# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Local (0x0)14# CHECK-NEXT: Binding: Local (0x0)
...@@ -17,7 +17,7 @@...@@ -17,7 +17,7 @@
17# CHECK-NEXT: Section: Undefined (0x0)17# CHECK-NEXT: Section: Undefined (0x0)
18# CHECK-NEXT: }18# CHECK-NEXT: }
19# CHECK-NEXT: Symbol {19# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: foo1@ (1)20# CHECK-NEXT: Name: foo1
21# CHECK-NEXT: Value: 0x100021# CHECK-NEXT: Value: 0x1000
22# CHECK-NEXT: Size: 022# CHECK-NEXT: Size: 0
23# CHECK-NEXT: Binding: Global (0x1)23# CHECK-NEXT: Binding: Global (0x1)
...@@ -26,7 +26,7 @@...@@ -26,7 +26,7 @@
26# CHECK-NEXT: Section: .text (0x4)26# CHECK-NEXT: Section: .text (0x4)
27# CHECK-NEXT: }27# CHECK-NEXT: }
28# CHECK-NEXT: Symbol {28# CHECK-NEXT: Symbol {
29# CHECK-NEXT: Name: foo11@ (6)29# CHECK-NEXT: Name: foo11
30# CHECK-NEXT: Value: 0x100130# CHECK-NEXT: Value: 0x1001
31# CHECK-NEXT: Size: 031# CHECK-NEXT: Size: 0
32# CHECK-NEXT: Binding: Global (0x1)32# CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/dynamic-list.s+11-11
...@@ -23,7 +23,7 @@...@@ -23,7 +23,7 @@
2323
24# CHECK: DynamicSymbols [24# CHECK: DynamicSymbols [
25# CHECK-NEXT: Symbol {25# CHECK-NEXT: Symbol {
26# CHECK-NEXT: Name: @26# CHECK-NEXT: Name:
27# CHECK-NEXT: Value: 0x027# CHECK-NEXT: Value: 0x0
28# CHECK-NEXT: Size: 028# CHECK-NEXT: Size: 0
29# CHECK-NEXT: Binding: Local29# CHECK-NEXT: Binding: Local
...@@ -32,7 +32,7 @@...@@ -32,7 +32,7 @@
32# CHECK-NEXT: Section: Undefined32# CHECK-NEXT: Section: Undefined
33# CHECK-NEXT: }33# CHECK-NEXT: }
34# CHECK-NEXT: Symbol {34# CHECK-NEXT: Symbol {
35# CHECK-NEXT: Name: foo1@35# CHECK-NEXT: Name: foo1
36# CHECK-NEXT: Value: 0x20100036# CHECK-NEXT: Value: 0x201000
37# CHECK-NEXT: Size: 037# CHECK-NEXT: Size: 0
38# CHECK-NEXT: Binding: Global (0x1)38# CHECK-NEXT: Binding: Global (0x1)
...@@ -54,7 +54,7 @@...@@ -54,7 +54,7 @@
5454
55# CHECK2: DynamicSymbols [55# CHECK2: DynamicSymbols [
56# CHECK2-NEXT: Symbol {56# CHECK2-NEXT: Symbol {
57# CHECK2-NEXT: Name: @57# CHECK2-NEXT: Name:
58# CHECK2-NEXT: Value: 0x058# CHECK2-NEXT: Value: 0x0
59# CHECK2-NEXT: Size: 059# CHECK2-NEXT: Size: 0
60# CHECK2-NEXT: Binding: Local60# CHECK2-NEXT: Binding: Local
...@@ -63,7 +63,7 @@...@@ -63,7 +63,7 @@
63# CHECK2-NEXT: Section: Undefined63# CHECK2-NEXT: Section: Undefined
64# CHECK2-NEXT: }64# CHECK2-NEXT: }
65# CHECK2-NEXT: Symbol {65# CHECK2-NEXT: Symbol {
66# CHECK2-NEXT: Name: foo1@66# CHECK2-NEXT: Name: foo1
67# CHECK2-NEXT: Value: 0x20100067# CHECK2-NEXT: Value: 0x201000
68# CHECK2-NEXT: Size: 068# CHECK2-NEXT: Size: 0
69# CHECK2-NEXT: Binding: Global (0x1)69# CHECK2-NEXT: Binding: Global (0x1)
...@@ -72,7 +72,7 @@...@@ -72,7 +72,7 @@
72# CHECK2-NEXT: Section: .text (0x4)72# CHECK2-NEXT: Section: .text (0x4)
73# CHECK2-NEXT: }73# CHECK2-NEXT: }
74# CHECK2-NEXT: Symbol {74# CHECK2-NEXT: Symbol {
75# CHECK2-NEXT: Name: foo2@75# CHECK2-NEXT: Name: foo2
76# CHECK2-NEXT: Value: 0x20100176# CHECK2-NEXT: Value: 0x201001
77# CHECK2-NEXT: Size: 077# CHECK2-NEXT: Size: 0
78# CHECK2-NEXT: Binding: Global (0x1)78# CHECK2-NEXT: Binding: Global (0x1)
...@@ -81,7 +81,7 @@...@@ -81,7 +81,7 @@
81# CHECK2-NEXT: Section: .text (0x4)81# CHECK2-NEXT: Section: .text (0x4)
82# CHECK2-NEXT: }82# CHECK2-NEXT: }
83# CHECK2-NEXT: Symbol {83# CHECK2-NEXT: Symbol {
84# CHECK2-NEXT: Name: foo31@84# CHECK2-NEXT: Name: foo31
85# CHECK2-NEXT: Value: 0x20100285# CHECK2-NEXT: Value: 0x201002
86# CHECK2-NEXT: Size: 086# CHECK2-NEXT: Size: 0
87# CHECK2-NEXT: Binding: Global (0x1)87# CHECK2-NEXT: Binding: Global (0x1)
...@@ -104,7 +104,7 @@...@@ -104,7 +104,7 @@
104104
105# CHECK3: DynamicSymbols [105# CHECK3: DynamicSymbols [
106# CHECK3-NEXT: Symbol {106# CHECK3-NEXT: Symbol {
107# CHECK3-NEXT: Name: @107# CHECK3-NEXT: Name:
108# CHECK3-NEXT: Value: 0x0108# CHECK3-NEXT: Value: 0x0
109# CHECK3-NEXT: Size: 0109# CHECK3-NEXT: Size: 0
110# CHECK3-NEXT: Binding: Local110# CHECK3-NEXT: Binding: Local
...@@ -113,7 +113,7 @@...@@ -113,7 +113,7 @@
113# CHECK3-NEXT: Section: Undefined113# CHECK3-NEXT: Section: Undefined
114# CHECK3-NEXT: }114# CHECK3-NEXT: }
115# CHECK3-NEXT: Symbol {115# CHECK3-NEXT: Symbol {
116# CHECK3-NEXT: Name: _start@116# CHECK3-NEXT: Name: _start
117# CHECK3-NEXT: Value: 0x201003117# CHECK3-NEXT: Value: 0x201003
118# CHECK3-NEXT: Size: 0118# CHECK3-NEXT: Size: 0
119# CHECK3-NEXT: Binding: Global (0x1)119# CHECK3-NEXT: Binding: Global (0x1)
...@@ -122,7 +122,7 @@...@@ -122,7 +122,7 @@
122# CHECK3-NEXT: Section: .text (0x4)122# CHECK3-NEXT: Section: .text (0x4)
123# CHECK3-NEXT: }123# CHECK3-NEXT: }
124# CHECK3-NEXT: Symbol {124# CHECK3-NEXT: Symbol {
125# CHECK3-NEXT: Name: foo1@125# CHECK3-NEXT: Name: foo1
126# CHECK3-NEXT: Value: 0x201000126# CHECK3-NEXT: Value: 0x201000
127# CHECK3-NEXT: Size: 0127# CHECK3-NEXT: Size: 0
128# CHECK3-NEXT: Binding: Global (0x1)128# CHECK3-NEXT: Binding: Global (0x1)
...@@ -131,7 +131,7 @@...@@ -131,7 +131,7 @@
131# CHECK3-NEXT: Section: .text (0x4)131# CHECK3-NEXT: Section: .text (0x4)
132# CHECK3-NEXT: }132# CHECK3-NEXT: }
133# CHECK3-NEXT: Symbol {133# CHECK3-NEXT: Symbol {
134# CHECK3-NEXT: Name: foo2@134# CHECK3-NEXT: Name: foo2
135# CHECK3-NEXT: Value: 0x201001135# CHECK3-NEXT: Value: 0x201001
136# CHECK3-NEXT: Size: 0136# CHECK3-NEXT: Size: 0
137# CHECK3-NEXT: Binding: Global (0x1)137# CHECK3-NEXT: Binding: Global (0x1)
...@@ -140,7 +140,7 @@...@@ -140,7 +140,7 @@
140# CHECK3-NEXT: Section: .text (0x4)140# CHECK3-NEXT: Section: .text (0x4)
141# CHECK3-NEXT: }141# CHECK3-NEXT: }
142# CHECK3-NEXT: Symbol {142# CHECK3-NEXT: Symbol {
143# CHECK3-NEXT: Name: foo31@143# CHECK3-NEXT: Name: foo31
144# CHECK3-NEXT: Value: 0x201002144# CHECK3-NEXT: Value: 0x201002
145# CHECK3-NEXT: Size: 0145# CHECK3-NEXT: Size: 0
146# CHECK3-NEXT: Binding: Global (0x1)146# CHECK3-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/dynamic-reloc.s+1-1
...@@ -18,7 +18,7 @@...@@ -18,7 +18,7 @@
18// CHECK-NEXT: Offset:18// CHECK-NEXT: Offset:
19// CHECK-NEXT: Size: [[RELASIZE:.*]]19// CHECK-NEXT: Size: [[RELASIZE:.*]]
20// CHECK-NEXT: Link: 120// CHECK-NEXT: Link: 1
21// CHECK-NEXT: Info: 021// CHECK-NEXT: Info: 7
22// CHECK-NEXT: AddressAlignment: 822// CHECK-NEXT: AddressAlignment: 8
23// CHECK-NEXT: EntrySize: 2423// CHECK-NEXT: EntrySize: 24
2424
deps/lld/test/ELF/dynsym-no-rosegment.s+2-2
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
55
6# CHECK: DynamicSymbols [6# CHECK: DynamicSymbols [
7# CHECK-NEXT: Symbol {7# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @ (0)8# CHECK-NEXT: Name:
9# CHECK-NEXT: Value: 0x09# CHECK-NEXT: Value: 0x0
10# CHECK-NEXT: Size: 010# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local11# CHECK-NEXT: Binding: Local
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14# CHECK-NEXT: Section: Undefined14# CHECK-NEXT: Section: Undefined
15# CHECK-NEXT: }15# CHECK-NEXT: }
16# CHECK-NEXT: Symbol {16# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: undef@17# CHECK-NEXT: Name: undef
18# CHECK-NEXT: Value: 0x018# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 019# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Global20# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/dynsym-pie.s+1-1
...@@ -50,7 +50,7 @@...@@ -50,7 +50,7 @@
5050
51# CHECK: DynamicSymbols [51# CHECK: DynamicSymbols [
52# CHECK-NEXT: Symbol {52# CHECK-NEXT: Symbol {
53# CHECK-NEXT: Name: @53# CHECK-NEXT: Name:
54# CHECK-NEXT: Value: 0x054# CHECK-NEXT: Value: 0x0
55# CHECK-NEXT: Size: 055# CHECK-NEXT: Size: 0
56# CHECK-NEXT: Binding: Local56# CHECK-NEXT: Binding: Local
deps/lld/test/ELF/edata-etext.s-1
...@@ -18,7 +18,6 @@...@@ -18,7 +18,6 @@
18# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA18# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA
19# CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS19# CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS
20# CHECK: SYMBOL TABLE:20# CHECK: SYMBOL TABLE:
21# CHECK-NEXT: 0000000000000000 *UND* 00000000
22# CHECK-NEXT: 0000000000202002 .data 00000000 _edata21# CHECK-NEXT: 0000000000202002 .data 00000000 _edata
23# CHECK-NEXT: 000000000020200a .bss 00000000 _end22# CHECK-NEXT: 000000000020200a .bss 00000000 _end
24# CHECK-NEXT: 0000000000201001 .text 00000000 _etext23# CHECK-NEXT: 0000000000201001 .text 00000000 _etext
deps/lld/test/ELF/emit-relocs-icf1.s created+32
...@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --emit-relocs --icf=all %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# CHECK: Relocations [
7# CHECK-NEXT: Section (3) .rela.text {
8# CHECK-NEXT: 0x201000 R_X86_64_64 .text 0x11
9# CHECK-NEXT: 0x201008 R_X86_64_64 .text 0x11
10# CHECK-NEXT: 0x201011 R_X86_64_64 .rodata 0x0
11# CHECK-NEXT: }
12# CHECK-NEXT: ]
13
14.rodata
15quux:
16.quad 0xfe
17
18.section .text.foo,"ax"
19foo:
20.quad quux
21
22.section .text.bar,"ax"
23bar:
24.quad quux
25
26.text
27.quad foo
28.quad bar
29
30.global _start
31_start:
32 nop
deps/lld/test/ELF/emit-relocs-icf2.s created+36
...@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --gc-sections --emit-relocs --icf=all %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# CHECK: Relocations [
7# CHECK-NEXT: Section (3) .rela.text {
8# CHECK-NEXT: 0x201000 R_X86_64_64 .text 0x11
9# CHECK-NEXT: 0x201008 R_X86_64_64 .text 0x11
10# CHECK-NEXT: 0x201011 R_X86_64_64 .rodata 0x0
11# CHECK-NEXT: }
12# CHECK-NEXT: ]
13
14.rodata
15quux:
16.quad 0xfe
17
18.section .text.foo,"ax"
19foo:
20.quad quux
21
22.section .text.bar,"ax"
23bar:
24.quad quux
25
26.section .text.baz,"ax"
27baz:
28.quad quux
29
30.text
31.quad foo
32.quad bar
33
34.global _start
35_start:
36 nop
deps/lld/test/ELF/empty-pack-dyn-relocs.s created+11
...@@ -0,0 +1,11 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o -o %t
5// RUN: llvm-readobj -sections %t | FileCheck %s
6
7.global _start
8_start:
9 nop
10
11# CHECK-NOT: Name: .relr.dyn
deps/lld/test/ELF/empty-ver.s+1-1
...@@ -29,7 +29,7 @@...@@ -29,7 +29,7 @@
29// CHECK-NEXT: Symbols [29// CHECK-NEXT: Symbols [
30// CHECK-NEXT: Symbol {30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Version: 031// CHECK-NEXT: Version: 0
32// CHECK-NEXT: Name: @32// CHECK-NEXT: Name:
33// CHECK-NEXT: }33// CHECK-NEXT: }
34// CHECK-NEXT: Symbol {34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Version: 235// CHECK-NEXT: Version: 2
deps/lld/test/ELF/empty-ver2.s+2-2
...@@ -8,11 +8,11 @@...@@ -8,11 +8,11 @@
8# CHECK: Symbols [8# CHECK: Symbols [
9# CHECK-NEXT: Symbol {9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Version: 010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @11# CHECK-NEXT: Name:
12# CHECK-NEXT: }12# CHECK-NEXT: }
13# CHECK-NEXT: Symbol {13# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Version: 114# CHECK-NEXT: Version: 1
15# CHECK-NEXT: Name: bar@@15# CHECK-NEXT: Name: bar@
16# CHECK-NEXT: }16# CHECK-NEXT: }
17# CHECK-NEXT: ]17# CHECK-NEXT: ]
1818
deps/lld/test/ELF/emulation-aarch64.s created+57
...@@ -0,0 +1,57 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
3# RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
4# RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
5# RUN: ld.lld -m aarch64elf %taarch64 -o %t3aarch64
6# RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
7# RUN: ld.lld -m aarch64_elf64_le_vec %taarch64 -o %t4aarch64
8# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
9# RUN: ld.lld %taarch64 -o %t5aarch64
10# RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
11# RUN: echo 'OUTPUT_FORMAT(elf64-littleaarch64)' > %t4aarch64.script
12# RUN: ld.lld %t4aarch64.script %taarch64 -o %t4aarch64
13# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
14# AARCH64: ElfHeader {
15# AARCH64-NEXT: Ident {
16# AARCH64-NEXT: Magic: (7F 45 4C 46)
17# AARCH64-NEXT: Class: 64-bit (0x2)
18# AARCH64-NEXT: DataEncoding: LittleEndian (0x1)
19# AARCH64-NEXT: FileVersion: 1
20# AARCH64-NEXT: OS/ABI: SystemV (0x0)
21# AARCH64-NEXT: ABIVersion: 0
22# AARCH64-NEXT: Unused: (00 00 00 00 00 00 00)
23# AARCH64-NEXT: }
24# AARCH64-NEXT: Type: Executable (0x2)
25# AARCH64-NEXT: Machine: EM_AARCH64 (0xB7)
26# AARCH64-NEXT: Version: 1
27# AARCH64-NEXT: Entry:
28# AARCH64-NEXT: ProgramHeaderOffset: 0x40
29# AARCH64-NEXT: SectionHeaderOffset:
30# AARCH64-NEXT: Flags [ (0x0)
31# AARCH64-NEXT: ]
32
33# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd
34# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script
35# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd
36# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
37# AARCH64-FBSD: ElfHeader {
38# AARCH64-FBSD-NEXT: Ident {
39# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46)
40# AARCH64-FBSD-NEXT: Class: 64-bit (0x2)
41# AARCH64-FBSD-NEXT: DataEncoding: LittleEndian (0x1)
42# AARCH64-FBSD-NEXT: FileVersion: 1
43# AARCH64-FBSD-NEXT: OS/ABI: FreeBSD (0x9)
44# AARCH64-FBSD-NEXT: ABIVersion: 0
45# AARCH64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
46# AARCH64-FBSD-NEXT: }
47# AARCH64-FBSD-NEXT: Type: Executable (0x2)
48# AARCH64-FBSD-NEXT: Machine: EM_AARCH64 (0xB7)
49# AARCH64-FBSD-NEXT: Version: 1
50# AARCH64-FBSD-NEXT: Entry:
51# AARCH64-FBSD-NEXT: ProgramHeaderOffset: 0x40
52# AARCH64-FBSD-NEXT: SectionHeaderOffset:
53# AARCH64-FBSD-NEXT: Flags [ (0x0)
54# AARCH64-FBSD-NEXT: ]
55
56.globl _start
57_start:
deps/lld/test/ELF/emulation-arm.s created+27
...@@ -0,0 +1,27 @@
1# REQUIRES: arm
2# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux %s -o %tarm
3# RUN: ld.lld -m armelf %tarm -o %t2arm
4# RUN: llvm-readobj -file-headers %t2arm | FileCheck --check-prefix=ARM %s
5# RUN: ld.lld -m armelf_linux_eabi %tarm -o %t3arm
6# RUN: llvm-readobj -file-headers %t3arm | FileCheck --check-prefix=ARM %s
7# RUN: ld.lld %tarm -o %t4arm
8# RUN: llvm-readobj -file-headers %t4arm | FileCheck --check-prefix=ARM %s
9# RUN: echo 'OUTPUT_FORMAT(elf32-littlearm)' > %t5arm.script
10# RUN: ld.lld %t5arm.script %tarm -o %t5arm
11# RUN: llvm-readobj -file-headers %t5arm | FileCheck --check-prefix=ARM %s
12# ARM: ElfHeader {
13# ARM-NEXT: Ident {
14# ARM-NEXT: Magic: (7F 45 4C 46)
15# ARM-NEXT: Class: 32-bit (0x1)
16# ARM-NEXT: DataEncoding: LittleEndian (0x1)
17# ARM-NEXT: FileVersion: 1
18# ARM-NEXT: OS/ABI: SystemV (0x0)
19# ARM-NEXT: ABIVersion: 0
20# ARM-NEXT: Unused: (00 00 00 00 00 00 00)
21# ARM-NEXT: }
22# ARM-NEXT: Type: Executable (0x2)
23# ARM-NEXT: Machine: EM_ARM (0x28)
24# ARM-NEXT: Version: 1
25
26.globl _start
27_start:
deps/lld/test/ELF/emulation-mips.s created+189
...@@ -0,0 +1,189 @@
1# REQUIRES: mips
2# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips
3# RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips
4# RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s
5# RUN: ld.lld %tmips -e _start -o %t3mips
6# RUN: llvm-readobj -file-headers %t3mips | FileCheck --check-prefix=MIPS %s
7# RUN: echo 'OUTPUT_FORMAT(elf32-tradbigmips)' > %tmips.script
8# RUN: ld.lld %tmips.script -e _start %tmips -o %t4mips
9# RUN: llvm-readobj -file-headers %t4mips | FileCheck --check-prefix=MIPS %s
10# MIPS: ElfHeader {
11# MIPS-NEXT: Ident {
12# MIPS-NEXT: Magic: (7F 45 4C 46)
13# MIPS-NEXT: Class: 32-bit (0x1)
14# MIPS-NEXT: DataEncoding: BigEndian (0x2)
15# MIPS-NEXT: FileVersion: 1
16# MIPS-NEXT: OS/ABI: SystemV (0x0)
17# MIPS-NEXT: ABIVersion: 1
18# MIPS-NEXT: Unused: (00 00 00 00 00 00 00)
19# MIPS-NEXT: }
20# MIPS-NEXT: Type: Executable (0x2)
21# MIPS-NEXT: Machine: EM_MIPS (0x8)
22# MIPS-NEXT: Version: 1
23# MIPS-NEXT: Entry:
24# MIPS-NEXT: ProgramHeaderOffset: 0x34
25# MIPS-NEXT: SectionHeaderOffset:
26# MIPS-NEXT: Flags [
27# MIPS-NEXT: EF_MIPS_ABI_O32
28# MIPS-NEXT: EF_MIPS_ARCH_32
29# MIPS-NEXT: EF_MIPS_CPIC
30# MIPS-NEXT: ]
31
32# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %tmipsel
33# RUN: ld.lld -m elf32ltsmip -e _start %tmipsel -o %t2mipsel
34# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
35# RUN: ld.lld -melf32ltsmip -e _start %tmipsel -o %t2mipsel
36# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
37# RUN: ld.lld %tmipsel -e _start -o %t3mipsel
38# RUN: llvm-readobj -file-headers %t3mipsel | FileCheck --check-prefix=MIPSEL %s
39# RUN: echo 'OUTPUT_FORMAT(elf32-tradlittlemips)' > %tmipsel.script
40# RUN: ld.lld %tmipsel.script -e _start %tmipsel -o %t4mipsel
41# RUN: llvm-readobj -file-headers %t4mipsel | FileCheck --check-prefix=MIPSEL %s
42# MIPSEL: ElfHeader {
43# MIPSEL-NEXT: Ident {
44# MIPSEL-NEXT: Magic: (7F 45 4C 46)
45# MIPSEL-NEXT: Class: 32-bit (0x1)
46# MIPSEL-NEXT: DataEncoding: LittleEndian (0x1)
47# MIPSEL-NEXT: FileVersion: 1
48# MIPSEL-NEXT: OS/ABI: SystemV (0x0)
49# MIPSEL-NEXT: ABIVersion: 1
50# MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00)
51# MIPSEL-NEXT: }
52# MIPSEL-NEXT: Type: Executable (0x2)
53# MIPSEL-NEXT: Machine: EM_MIPS (0x8)
54# MIPSEL-NEXT: Version: 1
55# MIPSEL-NEXT: Entry:
56# MIPSEL-NEXT: ProgramHeaderOffset: 0x34
57# MIPSEL-NEXT: SectionHeaderOffset:
58# MIPSEL-NEXT: Flags [
59# MIPSEL-NEXT: EF_MIPS_ABI_O32
60# MIPSEL-NEXT: EF_MIPS_ARCH_32
61# MIPSEL-NEXT: EF_MIPS_CPIC
62# MIPSEL-NEXT: ]
63
64# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux-gnuabin32 %s -o %tmipsn32
65# RUN: ld.lld -m elf32btsmipn32 -e _start %tmipsn32 -o %t2mipsn32
66# RUN: llvm-readobj -file-headers %t2mipsn32 | FileCheck --check-prefix=MIPSN32 %s
67# RUN: ld.lld %tmipsn32 -e _start -o %t3mipsn32
68# RUN: llvm-readobj -file-headers %t3mipsn32 | FileCheck --check-prefix=MIPSN32 %s
69# RUN: echo 'OUTPUT_FORMAT(elf32-ntradbigmips)' > %tmipsn32.script
70# RUN: ld.lld %tmipsn32.script -e _start %tmipsn32 -o %t4mipsn32
71# RUN: llvm-readobj -file-headers %t4mipsn32 | FileCheck --check-prefix=MIPSN32 %s
72# MIPSN32: ElfHeader {
73# MIPSN32-NEXT: Ident {
74# MIPSN32-NEXT: Magic: (7F 45 4C 46)
75# MIPSN32-NEXT: Class: 32-bit (0x1)
76# MIPSN32-NEXT: DataEncoding: BigEndian (0x2)
77# MIPSN32-NEXT: FileVersion: 1
78# MIPSN32-NEXT: OS/ABI: SystemV (0x0)
79# MIPSN32-NEXT: ABIVersion: 1
80# MIPSN32-NEXT: Unused: (00 00 00 00 00 00 00)
81# MIPSN32-NEXT: }
82# MIPSN32-NEXT: Type: Executable (0x2)
83# MIPSN32-NEXT: Machine: EM_MIPS (0x8)
84# MIPSN32-NEXT: Version: 1
85# MIPSN32-NEXT: Entry:
86# MIPSN32-NEXT: ProgramHeaderOffset: 0x34
87# MIPSN32-NEXT: SectionHeaderOffset:
88# MIPSN32-NEXT: Flags [
89# MIPSN32-NEXT: EF_MIPS_ABI2
90# MIPSN32-NEXT: EF_MIPS_ARCH_64
91# MIPSN32-NEXT: EF_MIPS_CPIC
92# MIPSN32-NEXT: ]
93
94# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux-gnuabin32 %s -o %tmipsn32el
95# RUN: ld.lld -m elf32ltsmipn32 -e _start %tmipsn32el -o %t2mipsn32el
96# RUN: llvm-readobj -file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
97# RUN: ld.lld -melf32ltsmipn32 -e _start %tmipsn32el -o %t2mipsn32el
98# RUN: llvm-readobj -file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
99# RUN: ld.lld %tmipsn32el -e _start -o %t3mipsn32el
100# RUN: llvm-readobj -file-headers %t3mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
101# RUN: echo 'OUTPUT_FORMAT(elf32-ntradlittlemips)' > %tmipsn32el.script
102# RUN: ld.lld %tmipsn32el.script -e _start %tmipsn32el -o %t4mipsn32el
103# RUN: llvm-readobj -file-headers %t4mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
104# MIPSN32EL: ElfHeader {
105# MIPSN32EL-NEXT: Ident {
106# MIPSN32EL-NEXT: Magic: (7F 45 4C 46)
107# MIPSN32EL-NEXT: Class: 32-bit (0x1)
108# MIPSN32EL-NEXT: DataEncoding: LittleEndian (0x1)
109# MIPSN32EL-NEXT: FileVersion: 1
110# MIPSN32EL-NEXT: OS/ABI: SystemV (0x0)
111# MIPSN32EL-NEXT: ABIVersion: 1
112# MIPSN32EL-NEXT: Unused: (00 00 00 00 00 00 00)
113# MIPSN32EL-NEXT: }
114# MIPSN32EL-NEXT: Type: Executable (0x2)
115# MIPSN32EL-NEXT: Machine: EM_MIPS (0x8)
116# MIPSN32EL-NEXT: Version: 1
117# MIPSN32EL-NEXT: Entry:
118# MIPSN32EL-NEXT: ProgramHeaderOffset: 0x34
119# MIPSN32EL-NEXT: SectionHeaderOffset:
120# MIPSN32EL-NEXT: Flags [
121# MIPSN32EL-NEXT: EF_MIPS_ABI2
122# MIPSN32EL-NEXT: EF_MIPS_ARCH_64
123# MIPSN32EL-NEXT: EF_MIPS_CPIC
124# MIPSN32EL-NEXT: ]
125
126# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -position-independent \
127# RUN: %s -o %tmips64
128# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64
129# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
130# RUN: ld.lld %tmips64 -e _start -o %t3mips64
131# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
132# RUN: echo 'OUTPUT_FORMAT(elf64-tradbigmips)' > %tmips64.script
133# RUN: ld.lld %tmips64.script -e _start %tmips64 -o %t4mips64
134# RUN: llvm-readobj -file-headers %t4mips64 | FileCheck --check-prefix=MIPS64 %s
135# MIPS64: ElfHeader {
136# MIPS64-NEXT: Ident {
137# MIPS64-NEXT: Magic: (7F 45 4C 46)
138# MIPS64-NEXT: Class: 64-bit (0x2)
139# MIPS64-NEXT: DataEncoding: BigEndian (0x2)
140# MIPS64-NEXT: FileVersion: 1
141# MIPS64-NEXT: OS/ABI: SystemV (0x0)
142# MIPS64-NEXT: ABIVersion: 0
143# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00)
144# MIPS64-NEXT: }
145# MIPS64-NEXT: Type: Executable (0x2)
146# MIPS64-NEXT: Machine: EM_MIPS (0x8)
147# MIPS64-NEXT: Version: 1
148# MIPS64-NEXT: Entry:
149# MIPS64-NEXT: ProgramHeaderOffset: 0x40
150# MIPS64-NEXT: SectionHeaderOffset:
151# MIPS64-NEXT: Flags [
152# MIPS64-NEXT: EF_MIPS_ARCH_64
153# MIPS64-NEXT: EF_MIPS_CPIC
154# MIPS64-NEXT: EF_MIPS_PIC
155# MIPS64-NEXT: ]
156
157# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
158# RUN: -position-independent %s -o %tmips64el
159# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el
160# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
161# RUN: ld.lld %tmips64el -e _start -o %t3mips64el
162# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
163# RUN: echo 'OUTPUT_FORMAT(elf64-tradlittlemips)' > %tmips64el.script
164# RUN: ld.lld %tmips64el.script -e _start %tmips64el -o %t4mips64el
165# RUN: llvm-readobj -file-headers %t4mips64el | FileCheck --check-prefix=MIPS64EL %s
166# MIPS64EL: ElfHeader {
167# MIPS64EL-NEXT: Ident {
168# MIPS64EL-NEXT: Magic: (7F 45 4C 46)
169# MIPS64EL-NEXT: Class: 64-bit (0x2)
170# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1)
171# MIPS64EL-NEXT: FileVersion: 1
172# MIPS64EL-NEXT: OS/ABI: SystemV (0x0)
173# MIPS64EL-NEXT: ABIVersion: 0
174# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00)
175# MIPS64EL-NEXT: }
176# MIPS64EL-NEXT: Type: Executable (0x2)
177# MIPS64EL-NEXT: Machine: EM_MIPS (0x8)
178# MIPS64EL-NEXT: Version: 1
179# MIPS64EL-NEXT: Entry:
180# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40
181# MIPS64EL-NEXT: SectionHeaderOffset:
182# MIPS64EL-NEXT: Flags [
183# MIPS64EL-NEXT: EF_MIPS_ARCH_64
184# MIPS64EL-NEXT: EF_MIPS_CPIC
185# MIPS64EL-NEXT: EF_MIPS_PIC
186# MIPS64EL-NEXT: ]
187
188.globl _start
189_start:
deps/lld/test/ELF/emulation-ppc.s created+107
...@@ -0,0 +1,107 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
3# RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
4# RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
5# RUN: ld.lld %tppc64 -o %t3ppc64
6# RUN: llvm-readobj -file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
7# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc)' > %tppc64.script
8# RUN: ld.lld %tppc64.script %tppc64 -o %t4ppc64
9# RUN: llvm-readobj -file-headers %t4ppc64 | FileCheck --check-prefix=PPC64 %s
10
11# PPC64: ElfHeader {
12# PPC64-NEXT: Ident {
13# PPC64-NEXT: Magic: (7F 45 4C 46)
14# PPC64-NEXT: Class: 64-bit (0x2)
15# PPC64-NEXT: DataEncoding: BigEndian (0x2)
16# PPC64-NEXT: FileVersion: 1
17# PPC64-NEXT: OS/ABI: SystemV (0x0)
18# PPC64-NEXT: ABIVersion: 0
19# PPC64-NEXT: Unused: (00 00 00 00 00 00 00)
20# PPC64-NEXT: }
21# PPC64-NEXT: Type: Executable (0x2)
22# PPC64-NEXT: Machine: EM_PPC64 (0x15)
23# PPC64-NEXT: Version: 1
24# PPC64-NEXT: Entry:
25# PPC64-NEXT: ProgramHeaderOffset: 0x40
26# PPC64-NEXT: SectionHeaderOffset:
27# PPC64-NEXT: Flags [ (0x2)
28# PPC64-NEXT: 0x2
29# PPC64-NEXT: ]
30# PPC64-NEXT: HeaderSize: 64
31# PPC64-NEXT: ProgramHeaderEntrySize: 56
32# PPC64-NEXT: ProgramHeaderCount:
33# PPC64-NEXT: SectionHeaderEntrySize: 64
34# PPC64-NEXT: SectionHeaderCount:
35# PPC64-NEXT: StringTableSectionIndex:
36# PPC64-NEXT: }
37
38# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
39# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
40# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd
41# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
42
43# PPC64-FBSD: ElfHeader {
44# PPC64-FBSD-NEXT: Ident {
45# PPC64-FBSD-NEXT: Magic: (7F 45 4C 46)
46# PPC64-FBSD-NEXT: Class: 64-bit (0x2)
47# PPC64-FBSD-NEXT: DataEncoding: BigEndian (0x2)
48# PPC64-FBSD-NEXT: FileVersion: 1
49# PPC64-FBSD-NEXT: OS/ABI: FreeBSD (0x9)
50# PPC64-FBSD-NEXT: ABIVersion: 0
51# PPC64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
52# PPC64-FBSD-NEXT: }
53# PPC64-FBSD-NEXT: Type: Executable (0x2)
54# PPC64-FBSD-NEXT: Machine: EM_PPC64 (0x15)
55# PPC64-FBSD-NEXT: Version: 1
56# PPC64-FBSD-NEXT: Entry:
57# PPC64-FBSD-NEXT: ProgramHeaderOffset: 0x40
58# PPC64-FBSD-NEXT: SectionHeaderOffset:
59# PPC64-FBSD-NEXT: Flags [ (0x2)
60# PPC64-FBSD-NEXT: 0x2
61# PPC64-FBSD-NEXT: ]
62# PPC64-FBSD-NEXT: HeaderSize: 64
63# PPC64-FBSD-NEXT: ProgramHeaderEntrySize: 56
64# PPC64-FBSD-NEXT: ProgramHeaderCount:
65# PPC64-FBSD-NEXT: SectionHeaderEntrySize: 64
66# PPC64-FBSD-NEXT: SectionHeaderCount:
67# PPC64-FBSD-NEXT: StringTableSectionIndex:
68# PPC64-FBSD-NEXT: }
69
70# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
71# RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
72# RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
73# RUN: ld.lld %tppc64le -o %t3ppc64le
74# RUN: llvm-readobj -file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s
75# RUN: echo 'OUTPUT_FORMAT(elf64-powerpcle)' > %tppc64le.script
76# RUN: ld.lld %tppc64le.script %tppc64le -o %t4ppc64le
77# RUN: llvm-readobj -file-headers %t4ppc64le | FileCheck --check-prefix=PPC64LE %s
78
79# PPC64LE: ElfHeader {
80# PPC64LE-NEXT: Ident {
81# PPC64LE-NEXT: Magic: (7F 45 4C 46)
82# PPC64LE-NEXT: Class: 64-bit (0x2)
83# PPC64LE-NEXT: DataEncoding: LittleEndian (0x1)
84# PPC64LE-NEXT: FileVersion: 1
85# PPC64LE-NEXT: OS/ABI: SystemV (0x0)
86# PPC64LE-NEXT: ABIVersion: 0
87# PPC64LE-NEXT: Unused: (00 00 00 00 00 00 00)
88# PPC64LE-NEXT: }
89# PPC64LE-NEXT: Type: Executable (0x2)
90# PPC64LE-NEXT: Machine: EM_PPC64 (0x15)
91# PPC64LE-NEXT: Version: 1
92# PPC64LE-NEXT: Entry:
93# PPC64LE-NEXT: ProgramHeaderOffset: 0x40
94# PPC64LE-NEXT: SectionHeaderOffset:
95# PPC64LE-NEXT: Flags [ (0x2)
96# PPC64LE-NEXT: 0x2
97# PPC64LE-NEXT: ]
98# PPC64LE-NEXT: HeaderSize: 64
99# PPC64LE-NEXT: ProgramHeaderEntrySize: 56
100# PPC64LE-NEXT: ProgramHeaderCount:
101# PPC64LE-NEXT: SectionHeaderEntrySize: 64
102# PPC64LE-NEXT: SectionHeaderCount:
103# PPC64LE-NEXT: StringTableSectionIndex:
104# PPC64LE-NEXT: }
105
106.globl _start
107_start:
deps/lld/test/ELF/emulation-x86.s created+211
...@@ -0,0 +1,211 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64
3# RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64
4# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s
5# RUN: ld.lld %tx64 -o %t3x64
6# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
8# RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
9# RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
10# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script
11# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
12# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
13# AMD64: ElfHeader {
14# AMD64-NEXT: Ident {
15# AMD64-NEXT: Magic: (7F 45 4C 46)
16# AMD64-NEXT: Class: 64-bit (0x2)
17# AMD64-NEXT: DataEncoding: LittleEndian (0x1)
18# AMD64-NEXT: FileVersion: 1
19# AMD64-NEXT: OS/ABI: FreeBSD (0x9)
20# AMD64-NEXT: ABIVersion: 0
21# AMD64-NEXT: Unused: (00 00 00 00 00 00 00)
22# AMD64-NEXT: }
23# AMD64-NEXT: Type: Executable (0x2)
24# AMD64-NEXT: Machine: EM_X86_64 (0x3E)
25# AMD64-NEXT: Version: 1
26# AMD64-NEXT: Entry:
27# AMD64-NEXT: ProgramHeaderOffset: 0x40
28# AMD64-NEXT: SectionHeaderOffset:
29# AMD64-NEXT: Flags [ (0x0)
30# AMD64-NEXT: ]
31# AMD64-NEXT: HeaderSize: 64
32# AMD64-NEXT: ProgramHeaderEntrySize: 56
33# AMD64-NEXT: ProgramHeaderCount:
34# AMD64-NEXT: SectionHeaderEntrySize: 64
35# AMD64-NEXT: SectionHeaderCount:
36# AMD64-NEXT: StringTableSectionIndex:
37# AMD64-NEXT: }
38
39# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx64
40# RUN: ld.lld -m elf_x86_64 %tx64 -o %t2x64
41# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
42# RUN: ld.lld %tx64 -o %t3x64
43# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
44# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64)' > %t4x64.script
45# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
46# RUN: ld.lld %tx64 -o %t4x64 %t4x64.script
47# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=X86-64 %s
48# X86-64: ElfHeader {
49# X86-64-NEXT: Ident {
50# X86-64-NEXT: Magic: (7F 45 4C 46)
51# X86-64-NEXT: Class: 64-bit (0x2)
52# X86-64-NEXT: DataEncoding: LittleEndian (0x1)
53# X86-64-NEXT: FileVersion: 1
54# X86-64-NEXT: OS/ABI: SystemV (0x0)
55# X86-64-NEXT: ABIVersion: 0
56# X86-64-NEXT: Unused: (00 00 00 00 00 00 00)
57# X86-64-NEXT: }
58# X86-64-NEXT: Type: Executable (0x2)
59# X86-64-NEXT: Machine: EM_X86_64 (0x3E)
60# X86-64-NEXT: Version: 1
61# X86-64-NEXT: Entry:
62# X86-64-NEXT: ProgramHeaderOffset: 0x40
63# X86-64-NEXT: SectionHeaderOffset:
64# X86-64-NEXT: Flags [ (0x0)
65# X86-64-NEXT: ]
66# X86-64-NEXT: HeaderSize: 64
67# X86-64-NEXT: ProgramHeaderEntrySize: 56
68# X86-64-NEXT: ProgramHeaderCount:
69# X86-64-NEXT: SectionHeaderEntrySize: 64
70# X86-64-NEXT: SectionHeaderCount:
71# X86-64-NEXT: StringTableSectionIndex:
72# X86-64-NEXT: }
73
74# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32
75# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32
76# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
77# RUN: ld.lld %tx32 -o %t3x32
78# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
79# RUN: echo 'OUTPUT_FORMAT(elf32-x86-64)' > %t4x32.script
80# RUN: ld.lld %t4x32.script %tx32 -o %t4x32
81# RUN: llvm-readobj -file-headers %t4x32 | FileCheck --check-prefix=X32 %s
82# X32: ElfHeader {
83# X32-NEXT: Ident {
84# X32-NEXT: Magic: (7F 45 4C 46)
85# X32-NEXT: Class: 32-bit (0x1)
86# X32-NEXT: DataEncoding: LittleEndian (0x1)
87# X32-NEXT: FileVersion: 1
88# X32-NEXT: OS/ABI: SystemV (0x0)
89# X32-NEXT: ABIVersion: 0
90# X32-NEXT: Unused: (00 00 00 00 00 00 00)
91# X32-NEXT: }
92# X32-NEXT: Type: Executable (0x2)
93# X32-NEXT: Machine: EM_X86_64 (0x3E)
94# X32-NEXT: Version: 1
95# X32-NEXT: Entry:
96# X32-NEXT: ProgramHeaderOffset: 0x34
97# X32-NEXT: SectionHeaderOffset:
98# X32-NEXT: Flags [ (0x0)
99# X32-NEXT: ]
100# X32-NEXT: HeaderSize: 52
101# X32-NEXT: ProgramHeaderEntrySize: 32
102# X32-NEXT: ProgramHeaderCount:
103# X32-NEXT: SectionHeaderEntrySize: 40
104# X32-NEXT: SectionHeaderCount:
105# X32-NEXT: StringTableSectionIndex:
106# X32-NEXT: }
107
108# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86
109# RUN: ld.lld -m elf_i386 %tx86 -o %t2x86
110# RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
111# RUN: ld.lld %tx86 -o %t3x86
112# RUN: llvm-readobj -file-headers %t3x86 | FileCheck --check-prefix=X86 %s
113# RUN: echo 'OUTPUT_FORMAT(elf32-i386)' > %t4x86.script
114# RUN: ld.lld %t4x86.script %tx86 -o %t4x86
115# RUN: llvm-readobj -file-headers %t4x86 | FileCheck --check-prefix=X86 %s
116# X86: ElfHeader {
117# X86-NEXT: Ident {
118# X86-NEXT: Magic: (7F 45 4C 46)
119# X86-NEXT: Class: 32-bit (0x1)
120# X86-NEXT: DataEncoding: LittleEndian (0x1)
121# X86-NEXT: FileVersion: 1
122# X86-NEXT: OS/ABI: SystemV (0x0)
123# X86-NEXT: ABIVersion: 0
124# X86-NEXT: Unused: (00 00 00 00 00 00 00)
125# X86-NEXT: }
126# X86-NEXT: Type: Executable (0x2)
127# X86-NEXT: Machine: EM_386 (0x3)
128# X86-NEXT: Version: 1
129# X86-NEXT: Entry:
130# X86-NEXT: ProgramHeaderOffset: 0x34
131# X86-NEXT: SectionHeaderOffset:
132# X86-NEXT: Flags [ (0x0)
133# X86-NEXT: ]
134# X86-NEXT: HeaderSize: 52
135# X86-NEXT: ProgramHeaderEntrySize: 32
136# X86-NEXT: ProgramHeaderCount:
137# X86-NEXT: SectionHeaderEntrySize: 40
138# X86-NEXT: SectionHeaderCount:
139# X86-NEXT: StringTableSectionIndex:
140# X86-NEXT: }
141
142# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
143# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd
144# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
145# RUN: ld.lld %tx86fbsd -o %t3x86fbsd
146# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
147# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script
148# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd
149# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
150# X86FBSD: ElfHeader {
151# X86FBSD-NEXT: Ident {
152# X86FBSD-NEXT: Magic: (7F 45 4C 46)
153# X86FBSD-NEXT: Class: 32-bit (0x1)
154# X86FBSD-NEXT: DataEncoding: LittleEndian (0x1)
155# X86FBSD-NEXT: FileVersion: 1
156# X86FBSD-NEXT: OS/ABI: FreeBSD (0x9)
157# X86FBSD-NEXT: ABIVersion: 0
158# X86FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
159# X86FBSD-NEXT: }
160# X86FBSD-NEXT: Type: Executable (0x2)
161# X86FBSD-NEXT: Machine: EM_386 (0x3)
162# X86FBSD-NEXT: Version: 1
163# X86FBSD-NEXT: Entry:
164# X86FBSD-NEXT: ProgramHeaderOffset: 0x34
165# X86FBSD-NEXT: SectionHeaderOffset:
166# X86FBSD-NEXT: Flags [ (0x0)
167# X86FBSD-NEXT: ]
168# X86FBSD-NEXT: HeaderSize: 52
169# X86FBSD-NEXT: ProgramHeaderEntrySize: 32
170# X86FBSD-NEXT: ProgramHeaderCount:
171# X86FBSD-NEXT: SectionHeaderEntrySize: 40
172# X86FBSD-NEXT: SectionHeaderCount:
173# X86FBSD-NEXT: StringTableSectionIndex:
174# X86FBSD-NEXT: }
175
176# RUN: llvm-mc -filetype=obj -triple=i586-intel-elfiamcu %s -o %tiamcu
177# RUN: ld.lld -m elf_iamcu %tiamcu -o %t2iamcu
178# RUN: llvm-readobj -file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
179# RUN: ld.lld %tiamcu -o %t3iamcu
180# RUN: llvm-readobj -file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
181# RUN: echo 'OUTPUT_FORMAT(elf32-iamcu)' > %t4iamcu.script
182# RUN: ld.lld %t4iamcu.script %tiamcu -o %t4iamcu
183# RUN: llvm-readobj -file-headers %t4iamcu | FileCheck --check-prefix=IAMCU %s
184# IAMCU: ElfHeader {
185# IAMCU-NEXT: Ident {
186# IAMCU-NEXT: Magic: (7F 45 4C 46)
187# IAMCU-NEXT: Class: 32-bit (0x1)
188# IAMCU-NEXT: DataEncoding: LittleEndian (0x1)
189# IAMCU-NEXT: FileVersion: 1
190# IAMCU-NEXT: OS/ABI: SystemV (0x0)
191# IAMCU-NEXT: ABIVersion: 0
192# IAMCU-NEXT: Unused: (00 00 00 00 00 00 00)
193# IAMCU-NEXT: }
194# IAMCU-NEXT: Type: Executable (0x2)
195# IAMCU-NEXT: Machine: EM_IAMCU (0x6)
196# IAMCU-NEXT: Version: 1
197# IAMCU-NEXT: Entry:
198# IAMCU-NEXT: ProgramHeaderOffset: 0x34
199# IAMCU-NEXT: SectionHeaderOffset:
200# IAMCU-NEXT: Flags [ (0x0)
201# IAMCU-NEXT: ]
202# IAMCU-NEXT: HeaderSize: 52
203# IAMCU-NEXT: ProgramHeaderEntrySize: 32
204# IAMCU-NEXT: ProgramHeaderCount:
205# IAMCU-NEXT: SectionHeaderEntrySize: 40
206# IAMCU-NEXT: SectionHeaderCount:
207# IAMCU-NEXT: StringTableSectionIndex:
208# IAMCU-NEXT: }
209
210.globl _start
211_start:
deps/lld/test/ELF/emulation.s deleted-396
...@@ -1,396 +0,0 @@
1# REQUIRES: x86,ppc,mips,aarch64
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64
3# RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64
4# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s
5# RUN: ld.lld %tx64 -o %t3x64
6# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
8# RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
9# RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
10# AMD64: ElfHeader {
11# AMD64-NEXT: Ident {
12# AMD64-NEXT: Magic: (7F 45 4C 46)
13# AMD64-NEXT: Class: 64-bit (0x2)
14# AMD64-NEXT: DataEncoding: LittleEndian (0x1)
15# AMD64-NEXT: FileVersion: 1
16# AMD64-NEXT: OS/ABI: FreeBSD (0x9)
17# AMD64-NEXT: ABIVersion: 0
18# AMD64-NEXT: Unused: (00 00 00 00 00 00 00)
19# AMD64-NEXT: }
20# AMD64-NEXT: Type: Executable (0x2)
21# AMD64-NEXT: Machine: EM_X86_64 (0x3E)
22# AMD64-NEXT: Version: 1
23# AMD64-NEXT: Entry:
24# AMD64-NEXT: ProgramHeaderOffset: 0x40
25# AMD64-NEXT: SectionHeaderOffset:
26# AMD64-NEXT: Flags [ (0x0)
27# AMD64-NEXT: ]
28# AMD64-NEXT: HeaderSize: 64
29# AMD64-NEXT: ProgramHeaderEntrySize: 56
30# AMD64-NEXT: ProgramHeaderCount:
31# AMD64-NEXT: SectionHeaderEntrySize: 64
32# AMD64-NEXT: SectionHeaderCount:
33# AMD64-NEXT: StringTableSectionIndex:
34# AMD64-NEXT: }
35
36# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx64
37# RUN: ld.lld -m elf_x86_64 %tx64 -o %t2x64
38# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
39# RUN: ld.lld %tx64 -o %t3x64
40# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
41# X86-64: ElfHeader {
42# X86-64-NEXT: Ident {
43# X86-64-NEXT: Magic: (7F 45 4C 46)
44# X86-64-NEXT: Class: 64-bit (0x2)
45# X86-64-NEXT: DataEncoding: LittleEndian (0x1)
46# X86-64-NEXT: FileVersion: 1
47# X86-64-NEXT: OS/ABI: SystemV (0x0)
48# X86-64-NEXT: ABIVersion: 0
49# X86-64-NEXT: Unused: (00 00 00 00 00 00 00)
50# X86-64-NEXT: }
51# X86-64-NEXT: Type: Executable (0x2)
52# X86-64-NEXT: Machine: EM_X86_64 (0x3E)
53# X86-64-NEXT: Version: 1
54# X86-64-NEXT: Entry:
55# X86-64-NEXT: ProgramHeaderOffset: 0x40
56# X86-64-NEXT: SectionHeaderOffset:
57# X86-64-NEXT: Flags [ (0x0)
58# X86-64-NEXT: ]
59# X86-64-NEXT: HeaderSize: 64
60# X86-64-NEXT: ProgramHeaderEntrySize: 56
61# X86-64-NEXT: ProgramHeaderCount:
62# X86-64-NEXT: SectionHeaderEntrySize: 64
63# X86-64-NEXT: SectionHeaderCount:
64# X86-64-NEXT: StringTableSectionIndex:
65# X86-64-NEXT: }
66
67# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32
68# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32
69# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
70# RUN: ld.lld %tx32 -o %t3x32
71# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
72# X32: ElfHeader {
73# X32-NEXT: Ident {
74# X32-NEXT: Magic: (7F 45 4C 46)
75# X32-NEXT: Class: 32-bit (0x1)
76# X32-NEXT: DataEncoding: LittleEndian (0x1)
77# X32-NEXT: FileVersion: 1
78# X32-NEXT: OS/ABI: SystemV (0x0)
79# X32-NEXT: ABIVersion: 0
80# X32-NEXT: Unused: (00 00 00 00 00 00 00)
81# X32-NEXT: }
82# X32-NEXT: Type: Executable (0x2)
83# X32-NEXT: Machine: EM_X86_64 (0x3E)
84# X32-NEXT: Version: 1
85# X32-NEXT: Entry:
86# X32-NEXT: ProgramHeaderOffset: 0x34
87# X32-NEXT: SectionHeaderOffset:
88# X32-NEXT: Flags [ (0x0)
89# X32-NEXT: ]
90# X32-NEXT: HeaderSize: 52
91# X32-NEXT: ProgramHeaderEntrySize: 32
92# X32-NEXT: ProgramHeaderCount:
93# X32-NEXT: SectionHeaderEntrySize: 40
94# X32-NEXT: SectionHeaderCount:
95# X32-NEXT: StringTableSectionIndex:
96# X32-NEXT: }
97
98# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86
99# RUN: ld.lld -m elf_i386 %tx86 -o %t2x86
100# RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
101# RUN: ld.lld %tx86 -o %t3x86
102# RUN: llvm-readobj -file-headers %t3x86 | FileCheck --check-prefix=X86 %s
103# X86: ElfHeader {
104# X86-NEXT: Ident {
105# X86-NEXT: Magic: (7F 45 4C 46)
106# X86-NEXT: Class: 32-bit (0x1)
107# X86-NEXT: DataEncoding: LittleEndian (0x1)
108# X86-NEXT: FileVersion: 1
109# X86-NEXT: OS/ABI: SystemV (0x0)
110# X86-NEXT: ABIVersion: 0
111# X86-NEXT: Unused: (00 00 00 00 00 00 00)
112# X86-NEXT: }
113# X86-NEXT: Type: Executable (0x2)
114# X86-NEXT: Machine: EM_386 (0x3)
115# X86-NEXT: Version: 1
116# X86-NEXT: Entry:
117# X86-NEXT: ProgramHeaderOffset: 0x34
118# X86-NEXT: SectionHeaderOffset:
119# X86-NEXT: Flags [ (0x0)
120# X86-NEXT: ]
121# X86-NEXT: HeaderSize: 52
122# X86-NEXT: ProgramHeaderEntrySize: 32
123# X86-NEXT: ProgramHeaderCount:
124# X86-NEXT: SectionHeaderEntrySize: 40
125# X86-NEXT: SectionHeaderCount:
126# X86-NEXT: StringTableSectionIndex:
127# X86-NEXT: }
128
129# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
130# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd
131# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s
132# RUN: ld.lld %tx86fbsd -o %t3x86fbsd
133# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
134# X86FBSD: ElfHeader {
135# X86FBSD-NEXT: Ident {
136# X86FBSD-NEXT: Magic: (7F 45 4C 46)
137# X86FBSD-NEXT: Class: 32-bit (0x1)
138# X86FBSD-NEXT: DataEncoding: LittleEndian (0x1)
139# X86FBSD-NEXT: FileVersion: 1
140# X86FBSD-NEXT: OS/ABI: FreeBSD (0x9)
141# X86FBSD-NEXT: ABIVersion: 0
142# X86FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
143# X86FBSD-NEXT: }
144# X86FBSD-NEXT: Type: Executable (0x2)
145# X86FBSD-NEXT: Machine: EM_386 (0x3)
146# X86FBSD-NEXT: Version: 1
147# X86FBSD-NEXT: Entry:
148# X86FBSD-NEXT: ProgramHeaderOffset: 0x34
149# X86FBSD-NEXT: SectionHeaderOffset:
150# X86FBSD-NEXT: Flags [ (0x0)
151# X86FBSD-NEXT: ]
152# X86FBSD-NEXT: HeaderSize: 52
153# X86FBSD-NEXT: ProgramHeaderEntrySize: 32
154# X86FBSD-NEXT: ProgramHeaderCount:
155# X86FBSD-NEXT: SectionHeaderEntrySize: 40
156# X86FBSD-NEXT: SectionHeaderCount:
157# X86FBSD-NEXT: StringTableSectionIndex:
158# X86FBSD-NEXT: }
159
160# RUN: llvm-mc -filetype=obj -triple=i586-intel-elfiamcu %s -o %tiamcu
161# RUN: ld.lld -m elf_iamcu %tiamcu -o %t2iamcu
162# RUN: llvm-readobj -file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
163# RUN: ld.lld %tiamcu -o %t3iamcu
164# RUN: llvm-readobj -file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
165# IAMCU: ElfHeader {
166# IAMCU-NEXT: Ident {
167# IAMCU-NEXT: Magic: (7F 45 4C 46)
168# IAMCU-NEXT: Class: 32-bit (0x1)
169# IAMCU-NEXT: DataEncoding: LittleEndian (0x1)
170# IAMCU-NEXT: FileVersion: 1
171# IAMCU-NEXT: OS/ABI: SystemV (0x0)
172# IAMCU-NEXT: ABIVersion: 0
173# IAMCU-NEXT: Unused: (00 00 00 00 00 00 00)
174# IAMCU-NEXT: }
175# IAMCU-NEXT: Type: Executable (0x2)
176# IAMCU-NEXT: Machine: EM_IAMCU (0x6)
177# IAMCU-NEXT: Version: 1
178# IAMCU-NEXT: Entry:
179# IAMCU-NEXT: ProgramHeaderOffset: 0x34
180# IAMCU-NEXT: SectionHeaderOffset:
181# IAMCU-NEXT: Flags [ (0x0)
182# IAMCU-NEXT: ]
183# IAMCU-NEXT: HeaderSize: 52
184# IAMCU-NEXT: ProgramHeaderEntrySize: 32
185# IAMCU-NEXT: ProgramHeaderCount:
186# IAMCU-NEXT: SectionHeaderEntrySize: 40
187# IAMCU-NEXT: SectionHeaderCount:
188# IAMCU-NEXT: StringTableSectionIndex:
189# IAMCU-NEXT: }
190
191# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
192# RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
193# RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
194# RUN: ld.lld %tppc64 -o %t3ppc64
195# RUN: llvm-readobj -file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
196# PPC64: ElfHeader {
197# PPC64-NEXT: Ident {
198# PPC64-NEXT: Magic: (7F 45 4C 46)
199# PPC64-NEXT: Class: 64-bit (0x2)
200# PPC64-NEXT: DataEncoding: BigEndian (0x2)
201# PPC64-NEXT: FileVersion: 1
202# PPC64-NEXT: OS/ABI: SystemV (0x0)
203# PPC64-NEXT: ABIVersion: 0
204# PPC64-NEXT: Unused: (00 00 00 00 00 00 00)
205# PPC64-NEXT: }
206# PPC64-NEXT: Type: Executable (0x2)
207# PPC64-NEXT: Machine: EM_PPC64 (0x15)
208# PPC64-NEXT: Version: 1
209# PPC64-NEXT: Entry:
210# PPC64-NEXT: ProgramHeaderOffset: 0x40
211# PPC64-NEXT: SectionHeaderOffset:
212# PPC64-NEXT: Flags [ (0x2)
213# PPC64-NEXT: 0x2
214# PPC64-NEXT: ]
215# PPC64-NEXT: HeaderSize: 64
216# PPC64-NEXT: ProgramHeaderEntrySize: 56
217# PPC64-NEXT: ProgramHeaderCount:
218# PPC64-NEXT: SectionHeaderEntrySize: 64
219# PPC64-NEXT: SectionHeaderCount:
220# PPC64-NEXT: StringTableSectionIndex:
221# PPC64-NEXT: }
222
223# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
224# RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
225# RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
226# RUN: ld.lld %tppc64le -o %t3ppc64le
227# RUN: llvm-readobj -file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s
228# PPC64LE: ElfHeader {
229# PPC64LE-NEXT: Ident {
230# PPC64LE-NEXT: Magic: (7F 45 4C 46)
231# PPC64LE-NEXT: Class: 64-bit (0x2)
232# PPC64LE-NEXT: DataEncoding: LittleEndian (0x1)
233# PPC64LE-NEXT: FileVersion: 1
234# PPC64LE-NEXT: OS/ABI: SystemV (0x0)
235# PPC64LE-NEXT: ABIVersion: 0
236# PPC64LE-NEXT: Unused: (00 00 00 00 00 00 00)
237# PPC64LE-NEXT: }
238# PPC64LE-NEXT: Type: Executable (0x2)
239# PPC64LE-NEXT: Machine: EM_PPC64 (0x15)
240# PPC64LE-NEXT: Version: 1
241# PPC64LE-NEXT: Entry:
242# PPC64LE-NEXT: ProgramHeaderOffset: 0x40
243# PPC64LE-NEXT: SectionHeaderOffset:
244# PPC64LE-NEXT: Flags [ (0x2)
245# PPC64LE-NEXT: 0x2
246# PPC64LE-NEXT: ]
247# PPC64LE-NEXT: HeaderSize: 64
248# PPC64LE-NEXT: ProgramHeaderEntrySize: 56
249# PPC64LE-NEXT: ProgramHeaderCount:
250# PPC64LE-NEXT: SectionHeaderEntrySize: 64
251# PPC64LE-NEXT: SectionHeaderCount:
252# PPC64LE-NEXT: StringTableSectionIndex:
253# PPC64LE-NEXT: }
254
255# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips
256# RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips
257# RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s
258# RUN: ld.lld %tmips -e _start -o %t3mips
259# RUN: llvm-readobj -file-headers %t3mips | FileCheck --check-prefix=MIPS %s
260# MIPS: ElfHeader {
261# MIPS-NEXT: Ident {
262# MIPS-NEXT: Magic: (7F 45 4C 46)
263# MIPS-NEXT: Class: 32-bit (0x1)
264# MIPS-NEXT: DataEncoding: BigEndian (0x2)
265# MIPS-NEXT: FileVersion: 1
266# MIPS-NEXT: OS/ABI: SystemV (0x0)
267# MIPS-NEXT: ABIVersion: 1
268# MIPS-NEXT: Unused: (00 00 00 00 00 00 00)
269# MIPS-NEXT: }
270# MIPS-NEXT: Type: Executable (0x2)
271# MIPS-NEXT: Machine: EM_MIPS (0x8)
272# MIPS-NEXT: Version: 1
273# MIPS-NEXT: Entry:
274# MIPS-NEXT: ProgramHeaderOffset: 0x34
275# MIPS-NEXT: SectionHeaderOffset:
276# MIPS-NEXT: Flags [
277# MIPS-NEXT: EF_MIPS_ABI_O32
278# MIPS-NEXT: EF_MIPS_ARCH_32
279# MIPS-NEXT: EF_MIPS_CPIC
280# MIPS-NEXT: ]
281
282# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %tmipsel
283# RUN: ld.lld -m elf32ltsmip -e _start %tmipsel -o %t2mipsel
284# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
285# RUN: ld.lld -melf32ltsmip -e _start %tmipsel -o %t2mipsel
286# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
287# RUN: ld.lld %tmipsel -e _start -o %t3mipsel
288# RUN: llvm-readobj -file-headers %t3mipsel | FileCheck --check-prefix=MIPSEL %s
289# MIPSEL: ElfHeader {
290# MIPSEL-NEXT: Ident {
291# MIPSEL-NEXT: Magic: (7F 45 4C 46)
292# MIPSEL-NEXT: Class: 32-bit (0x1)
293# MIPSEL-NEXT: DataEncoding: LittleEndian (0x1)
294# MIPSEL-NEXT: FileVersion: 1
295# MIPSEL-NEXT: OS/ABI: SystemV (0x0)
296# MIPSEL-NEXT: ABIVersion: 1
297# MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00)
298# MIPSEL-NEXT: }
299# MIPSEL-NEXT: Type: Executable (0x2)
300# MIPSEL-NEXT: Machine: EM_MIPS (0x8)
301# MIPSEL-NEXT: Version: 1
302# MIPSEL-NEXT: Entry:
303# MIPSEL-NEXT: ProgramHeaderOffset: 0x34
304# MIPSEL-NEXT: SectionHeaderOffset:
305# MIPSEL-NEXT: Flags [
306# MIPSEL-NEXT: EF_MIPS_ABI_O32
307# MIPSEL-NEXT: EF_MIPS_ARCH_32
308# MIPSEL-NEXT: EF_MIPS_CPIC
309# MIPSEL-NEXT: ]
310
311# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -position-independent \
312# RUN: %s -o %tmips64
313# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64
314# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
315# RUN: ld.lld %tmips64 -e _start -o %t3mips64
316# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
317# MIPS64: ElfHeader {
318# MIPS64-NEXT: Ident {
319# MIPS64-NEXT: Magic: (7F 45 4C 46)
320# MIPS64-NEXT: Class: 64-bit (0x2)
321# MIPS64-NEXT: DataEncoding: BigEndian (0x2)
322# MIPS64-NEXT: FileVersion: 1
323# MIPS64-NEXT: OS/ABI: SystemV (0x0)
324# MIPS64-NEXT: ABIVersion: 0
325# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00)
326# MIPS64-NEXT: }
327# MIPS64-NEXT: Type: Executable (0x2)
328# MIPS64-NEXT: Machine: EM_MIPS (0x8)
329# MIPS64-NEXT: Version: 1
330# MIPS64-NEXT: Entry:
331# MIPS64-NEXT: ProgramHeaderOffset: 0x40
332# MIPS64-NEXT: SectionHeaderOffset:
333# MIPS64-NEXT: Flags [
334# MIPS64-NEXT: EF_MIPS_ARCH_64
335# MIPS64-NEXT: EF_MIPS_CPIC
336# MIPS64-NEXT: EF_MIPS_PIC
337# MIPS64-NEXT: ]
338
339# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
340# RUN: -position-independent %s -o %tmips64el
341# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el
342# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
343# RUN: ld.lld %tmips64el -e _start -o %t3mips64el
344# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
345# MIPS64EL: ElfHeader {
346# MIPS64EL-NEXT: Ident {
347# MIPS64EL-NEXT: Magic: (7F 45 4C 46)
348# MIPS64EL-NEXT: Class: 64-bit (0x2)
349# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1)
350# MIPS64EL-NEXT: FileVersion: 1
351# MIPS64EL-NEXT: OS/ABI: SystemV (0x0)
352# MIPS64EL-NEXT: ABIVersion: 0
353# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00)
354# MIPS64EL-NEXT: }
355# MIPS64EL-NEXT: Type: Executable (0x2)
356# MIPS64EL-NEXT: Machine: EM_MIPS (0x8)
357# MIPS64EL-NEXT: Version: 1
358# MIPS64EL-NEXT: Entry:
359# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40
360# MIPS64EL-NEXT: SectionHeaderOffset:
361# MIPS64EL-NEXT: Flags [
362# MIPS64EL-NEXT: EF_MIPS_ARCH_64
363# MIPS64EL-NEXT: EF_MIPS_CPIC
364# MIPS64EL-NEXT: EF_MIPS_PIC
365# MIPS64EL-NEXT: ]
366
367# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
368# RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
369# RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
370# RUN: ld.lld -m aarch64elf %taarch64 -o %t3aarch64
371# RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
372# RUN: ld.lld -m aarch64_elf64_le_vec %taarch64 -o %t4aarch64
373# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
374# RUN: ld.lld %taarch64 -o %t5aarch64
375# RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
376# AARCH64: ElfHeader {
377# AARCH64-NEXT: Ident {
378# AARCH64-NEXT: Magic: (7F 45 4C 46)
379# AARCH64-NEXT: Class: 64-bit (0x2)
380# AARCH64-NEXT: DataEncoding: LittleEndian (0x1)
381# AARCH64-NEXT: FileVersion: 1
382# AARCH64-NEXT: OS/ABI: SystemV (0x0)
383# AARCH64-NEXT: ABIVersion: 0
384# AARCH64-NEXT: Unused: (00 00 00 00 00 00 00)
385# AARCH64-NEXT: }
386# AARCH64-NEXT: Type: Executable (0x2)
387# AARCH64-NEXT: Machine: EM_AARCH64 (0xB7)
388# AARCH64-NEXT: Version: 1
389# AARCH64-NEXT: Entry:
390# AARCH64-NEXT: ProgramHeaderOffset: 0x40
391# AARCH64-NEXT: SectionHeaderOffset:
392# AARCH64-NEXT: Flags [ (0x0)
393# AARCH64-NEXT: ]
394
395.globl _start
396_start:
deps/lld/test/ELF/execute-only-mixed-data.s+1-1
...@@ -16,7 +16,7 @@...@@ -16,7 +16,7 @@
16// RUN: }" > %t.lds16// RUN: }" > %t.lds
17// RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&117// RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1
1818
19// CHECK: -execute-only does not support intermingling data and code19// CHECK: cannot place {{.*}}:(.rodata.foo) into .text: -execute-only does not support intermingling data and code
2020
21 br lr21 br lr
2222
deps/lld/test/ELF/format-binary.test+12
...@@ -55,3 +55,15 @@...@@ -55,3 +55,15 @@
55# CHECK-NEXT: Other: 055# CHECK-NEXT: Other: 0
56# CHECK-NEXT: Section: Absolute56# CHECK-NEXT: Section: Absolute
57# CHECK-NEXT: }57# CHECK-NEXT: }
58
59# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64)' > %t.script
60# RUN: ld.lld -b binary %t.binary -T %t.script -o %t.out
61# RUN: llvm-readobj %t.out -sections -section-data -symbols | FileCheck -check-prefix=X86-64 %s
62
63# X86-64: Format: ELF64-x86-64
64
65# RUN: echo 'OUTPUT_FORMAT("elf64-x86-64")' > %t.script
66# RUN: ld.lld -b binary %t.binary -T %t.script -o %t.out
67# RUN: llvm-readobj %t.out -sections -section-data -symbols | FileCheck -check-prefix=X86-64-in-quotes %s
68
69# X86-64-in-quotes: Format: ELF64-x86-64
deps/lld/test/ELF/gc-sections-implicit-addend.s+3-3
...@@ -12,10 +12,10 @@...@@ -12,10 +12,10 @@
12# CHECK-NEXT: SHF_MERGE12# CHECK-NEXT: SHF_MERGE
13# CHECK-NEXT: SHF_STRINGS13# CHECK-NEXT: SHF_STRINGS
14# CHECK-NEXT: ]14# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x100B415# CHECK-NEXT: Address: 0x4000B4
1616
17# 0x100B4 == 6571617# 0x4000B4 == 4194484
18# DISASM: leal 65716, %eax18# DISASM: leal 4194484, %eax
1919
20 .section .foo,"aMS",@progbits,120 .section .foo,"aMS",@progbits,1
21 .byte 021 .byte 0
deps/lld/test/ELF/gc-sections-linker-defined-symbol.s+1-1
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
4# RUN: ld.lld %t.o -o %t.so --gc-sections -shared4# RUN: ld.lld %t.o -o %t.so --gc-sections -shared
5# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s5# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
66
7# CHECK: Name: _end@7# CHECK: Name: _end
8# CHECK-NEXT: Value:8# CHECK-NEXT: Value:
9# CHECK-NEXT: Size:9# CHECK-NEXT: Size:
10# CHECK-NEXT: Binding: Global10# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/gdb-index-base-addr.s+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
3# RUN: ld.lld --gdb-index %t1.o -o %t3# RUN: ld.lld --gdb-index %t1.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
55
6# CHECK: .gnu_index contents:6# CHECK: .gdb_index contents:
7# CHECK: Address area offset = 0x28, has 2 entries:7# CHECK: Address area offset = 0x28, has 2 entries:
8# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 08# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
9# CHECK-NEXT: Low/High address = [0x201003, 0x201006) (Size: 0x3), CU id = 09# CHECK-NEXT: Low/High address = [0x201003, 0x201006) (Size: 0x3), CU id = 0
deps/lld/test/ELF/gdb-index-dwarf5-low-high.s created+49
...@@ -0,0 +1,49 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld --gdb-index %t.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
5
6# CHECK: Address area offset = 0x28, has 1 entries:
7# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
8
9 .text
10 .globl main
11main: # @main
12.Lfunc_begin0:
13 retq
14.Lfunc_end0:
15 .section .debug_abbrev,"",@progbits
16 .byte 1 # Abbreviation Code
17 .byte 17 # DW_TAG_compile_unit
18 .byte 0 # DW_CHILDREN_no
19 .byte 115 # DW_AT_addr_base
20 .byte 23 # DW_FORM_sec_offset
21 .byte 17 # DW_AT_low_pc
22 .byte 27 # DW_FORM_addrx
23 .byte 18 # DW_AT_high_pc
24 .byte 6 # DW_FORM_data4
25 .byte 0 # EOM(1)
26 .byte 0 # EOM(2)
27 .byte 0 # EOM(3)
28
29 .section .debug_info,"",@progbits
30.Lcu_begin0:
31 .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
32.Ldebug_info_start0:
33 .short 5 # DWARF version number
34 .byte 1 # DWARF Unit Type
35 .byte 8 # Address Size (in bytes)
36 .long .debug_abbrev # Offset Into Abbrev. Section
37 .byte 1 # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit
38 .long .Laddr_table_base0 # DW_AT_addr_base
39 .byte 0 # DW_AT_low_pc
40 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
41.Ldebug_info_end0:
42
43 .section .debug_addr,"",@progbits
44 .long 12
45 .short 5
46 .byte 8
47 .byte 0
48.Laddr_table_base0:
49 .quad .Lfunc_begin0
deps/lld/test/ELF/gdb-index-invalid-ranges.s created+42
...@@ -0,0 +1,42 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: not ld.lld --gdb-index -e main %t.o -o %t 2>&1 | FileCheck %s
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index-invalid-ranges.obj.s -o %t2.o
5# RUN: llvm-ar rc %t.a %t.o
6# RUN: not ld.lld --gdb-index -e main %t2.o %t.a -o %t 2>&1 | FileCheck --check-prefix=ARCHIVE %s
7
8# CHECK: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
9# ARCHIVE: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
10
11.section .text.foo1,"ax",@progbits
12.globl f1
13.Lfunc_begin0:
14f1:
15 nop
16.Lfunc_end0:
17
18.section .debug_abbrev,"",@progbits
19.byte 1 # Abbreviation Code
20.byte 17 # DW_TAG_compile_unit
21.byte 0 # DW_CHILDREN_no
22.byte 85 # DW_AT_ranges
23.byte 23 # DW_FORM_sec_offset
24.byte 0 # EOM(1)
25.byte 0 # EOM(2)
26.byte 0 # EOM(3)
27
28.section .debug_info,"",@progbits
29.Lcu_begin0:
30.long .Lunit_end0-.Lunit_begin0 # Length of Unit
31.Lunit_begin0:
32.short 4 # DWARF version number
33.long .debug_abbrev # Offset Into Abbrev. Section
34.byte 8 # Address Size (in bytes)
35.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
36.long .Ldebug_ranges0 # DW_AT_ranges
37.Lunit_end0:
38
39.section .debug_ranges,"",@progbits
40.Ldebug_ranges0:
41.quad .Lfunc_begin0
42.quad .Lfunc_end0
deps/lld/test/ELF/gdb-index-multiple-cu-2.s created+36
...@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/gdb-index-multiple-cu-2.s -o %t1.o
4# RUN: ld.lld --gdb-index %t.o %t1.o -o %t
5# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
6
7# %t.o has 2 CUs while %t1 has 1, thus _start in %t1.o should have CuIndex 2.
8# Attributes << 24 | CuIndex = 48 << 24 | 2 = 0x30000002
9# CHECK: Constant pool
10# CHECK-NEXT: 0(0x0): 0x30000002
11
12.section .debug_abbrev,"",@progbits
13 .byte 1 # Abbreviation Code
14 .byte 17 # DW_TAG_compile_unit
15 .byte 0 # DW_CHILDREN_yes
16 .byte 0 # EOM(1)
17 .byte 0 # EOM(2)
18 .byte 0
19
20.section .debug_info,"",@progbits
21.Lcu_begin0:
22 .long .Lcu_end0 - .Lcu_begin0 - 4
23 .short 4 # DWARF version number
24 .long 0 # Offset Into Abbrev. Section
25 .byte 4 # Address Size
26 .byte 1 # Abbrev [1] DW_TAG_compile_unit
27 .byte 0
28.Lcu_end0:
29.Lcu_begin1:
30 .long .Lcu_end1 - .Lcu_begin1 - 4
31 .short 4 # DWARF version number
32 .long 0 # Offset Into Abbrev. Section
33 .byte 4 # Address Size
34 .byte 1 # Abbrev [1] DW_TAG_compile_unit
35 .byte 0
36.Lcu_end1:
deps/lld/test/ELF/gdb-index-multiple-cu.s created+88
...@@ -0,0 +1,88 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --gdb-index %t.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
5
6# CuIndexAndAttrs of _start:
7# Attributes << 24 | CuIndex = 48 << 24 | 0 = 0x30000000
8# CuIndexAndAttrs of foo:
9# Attributes << 24 | CuIndex = 48 << 24 | 1 = 0x30000001
10# CHECK: Symbol table
11# CHECK-DAG: String name: _start, CU vector index: 0
12# CHECK-DAG: String name: foo, CU vector index: 1
13# CHECK: Constant pool
14# CHECK-NEXT: 0(0x0): 0x30000000
15# CHECK-NEXT: 1(0x8): 0x30000001
16
17.globl _start, foo
18_start:
19foo:
20
21.section .debug_abbrev,"",@progbits
22 .byte 1 # Abbreviation Code
23 .byte 17 # DW_TAG_compile_unit
24 .byte 1 # DW_CHILDREN_yes
25 .ascii "\264B" # DW_AT_GNU_pubnames
26 .byte 25 # DW_FORM_flag_present
27 .byte 0 # EOM(1)
28 .byte 0 # EOM(2)
29 .byte 2 # Abbreviation Code
30 .byte 46 # DW_TAG_subprogram
31 .byte 0 # DW_CHILDREN_no
32 .byte 3 # DW_AT_name
33 .byte 8 # DW_FORM_string
34 .byte 0 # EOM(1)
35 .byte 0 # EOM(2)
36 .byte 0
37
38.section .debug_info,"",@progbits
39.Lcu_begin0:
40 .long .Lcu_end0 - .Lcu_begin0 - 4
41 .short 4 # DWARF version number
42 .long 0 # Offset Into Abbrev. Section
43 .byte 4 # Address Size
44.Ldie0:
45 .byte 1 # Abbrev [1] DW_TAG_compile_unit
46 .byte 2 # Abbrev [2] DW_TAG_subprogram
47 .asciz "_start" # DW_AT_name
48 .byte 0
49 .byte 0
50.Lcu_end0:
51.Lcu_begin1:
52 .long .Lcu_end1 - .Lcu_begin1 - 4
53 .short 4 # DWARF version number
54 .long 0 # Offset Into Abbrev. Section
55 .byte 4 # Address Size
56.Ldie1:
57 .byte 1 # Abbrev [1] DW_TAG_compile_unit
58 .byte 2 # Abbrev [2] DW_TAG_subprogram
59 .asciz "foo" # DW_AT_name
60 .byte 0
61.Lcu_end1:
62
63# Swap sets to test the case where pubnames are in a
64# different order than the CUs they refer to.
65.section .debug_gnu_pubnames,"",@progbits
66 # CuIndex: 1
67 .long .LpubNames_end1 - .LpubNames_begin1
68.LpubNames_begin1:
69 .short 2 # Version
70 .long .Lcu_begin1 # CU Offset
71 .long .Lcu_end1 - .Lcu_begin1
72 .long .Ldie1 - .Lcu_begin1
73 .byte 48 # Attributes: FUNCTION, EXTERNAL
74 .asciz "foo" # External Name
75 .long 0
76.LpubNames_end1:
77
78 # CuIndex: 0
79 .long .LpubNames_end0 - .LpubNames_begin0
80.LpubNames_begin0:
81 .short 2 # Version
82 .long .Lcu_begin0 # CU Offset
83 .long .Lcu_end0 - .Lcu_begin0
84 .long .Ldie0 - .Lcu_begin0
85 .byte 48 # Attributes: FUNCTION, EXTERNAL
86 .asciz "_start" # External Name
87 .long 0
88.LpubNames_end0:
deps/lld/test/ELF/gdb-index-no-debug.s created+8
...@@ -0,0 +1,8 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -o %t.exe -gdb-index %t.o
4# RUN: llvm-objdump --section-headers %t.exe | FileCheck %s
5# CHECK-NOT: .gdb_index
6
7.global _start
8_start:
deps/lld/test/ELF/gdb-index-ranges.s+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
3# RUN: ld.lld --gdb-index -e main %t.o -o %t3# RUN: ld.lld --gdb-index -e main %t.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
55
6# CHECK: .gnu_index contents:6# CHECK: .gdb_index contents:
7# CHECK: Address area offset = 0x28, has 2 entries:7# CHECK: Address area offset = 0x28, has 2 entries:
8# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 08# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
9# CHECK-NEXT: Low/High address = [0x201001, 0x201003) (Size: 0x2), CU id = 09# CHECK-NEXT: Low/High address = [0x201001, 0x201003) (Size: 0x2), CU id = 0
deps/lld/test/ELF/gdb-index-rng-lists.s created+202
...@@ -0,0 +1,202 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: ld.lld --gdb-index %t1.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
5
6## The code contains DWARF v5 sections .debug_rnglists and .debug_addr.
7## Check we are able to build the correct address
8## area using address range lists.
9
10# CHECK: .gdb_index contents:
11# CHECK: Address area offset = 0x28, has 2 entries:
12# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
13# CHECK-NEXT: Low/High address = [0x201001, 0x201003) (Size: 0x2), CU id = 0
14
15.text
16.section .text._Z3zedv,"ax",@progbits
17.Lfunc_begin0:
18 retq
19.Lfunc_end0:
20
21.section .text.main,"ax",@progbits
22.Lfunc_begin1:
23 retq
24 retq
25.Lfunc_end1:
26
27.section .debug_str_offsets,"",@progbits
28.long 32
29.short 5
30.short 0
31.Lstr_offsets_base0:
32 .long .Linfo_string0
33 .long .Linfo_string0
34 .long .Linfo_string0
35 .long .Linfo_string0
36 .long .Linfo_string0
37 .long .Linfo_string0
38 .long .Linfo_string0
39
40.section .debug_str,"MS",@progbits,1
41.Linfo_string0:
42 .asciz "stub"
43
44.section .debug_abbrev,"",@progbits
45 .byte 1 # Abbreviation Code
46 .byte 17 # DW_TAG_compile_unit
47 .byte 1 # DW_CHILDREN_yes
48 .byte 37 # DW_AT_producer
49 .byte 37 # DW_FORM_strx1
50 .byte 19 # DW_AT_language
51 .byte 5 # DW_FORM_data2
52 .byte 3 # DW_AT_name
53 .byte 37 # DW_FORM_strx1
54 .byte 114 # DW_AT_str_offsets_base
55 .byte 23 # DW_FORM_sec_offset
56 .byte 16 # DW_AT_stmt_list
57 .byte 23 # DW_FORM_sec_offset
58 .byte 27 # DW_AT_comp_dir
59 .byte 37 # DW_FORM_strx1
60 .byte 115 # DW_AT_addr_base
61 .byte 23 # DW_FORM_sec_offset
62 .byte 17 # DW_AT_low_pc
63 .byte 1 # DW_FORM_addr
64 .byte 85 # DW_AT_ranges
65 .byte 35 # DW_FORM_rnglistx
66 .byte 116 # DW_AT_rnglists_base
67 .byte 23 # DW_FORM_sec_offset
68 .byte 0 # EOM(1)
69 .byte 0 # EOM(2)
70 .byte 2 # Abbreviation Code
71 .byte 46 # DW_TAG_subprogram
72 .byte 0 # DW_CHILDREN_no
73 .byte 17 # DW_AT_low_pc
74 .byte 27 # DW_FORM_addrx
75 .byte 18 # DW_AT_high_pc
76 .byte 6 # DW_FORM_data4
77 .byte 64 # DW_AT_frame_base
78 .byte 24 # DW_FORM_exprloc
79 .byte 110 # DW_AT_linkage_name
80 .byte 37 # DW_FORM_strx1
81 .byte 3 # DW_AT_name
82 .byte 37 # DW_FORM_strx1
83 .byte 58 # DW_AT_decl_file
84 .byte 11 # DW_FORM_data1
85 .byte 59 # DW_AT_decl_line
86 .byte 11 # DW_FORM_data1
87 .byte 73 # DW_AT_type
88 .byte 19 # DW_FORM_ref4
89 .byte 63 # DW_AT_external
90 .byte 25 # DW_FORM_flag_present
91 .byte 0 # EOM(1)
92 .byte 0 # EOM(2)
93 .byte 3 # Abbreviation Code
94 .byte 46 # DW_TAG_subprogram
95 .byte 0 # DW_CHILDREN_no
96 .byte 17 # DW_AT_low_pc
97 .byte 27 # DW_FORM_addrx
98 .byte 18 # DW_AT_high_pc
99 .byte 6 # DW_FORM_data4
100 .byte 64 # DW_AT_frame_base
101 .byte 24 # DW_FORM_exprloc
102 .byte 3 # DW_AT_name
103 .byte 37 # DW_FORM_strx1
104 .byte 58 # DW_AT_decl_file
105 .byte 11 # DW_FORM_data1
106 .byte 59 # DW_AT_decl_line
107 .byte 11 # DW_FORM_data1
108 .byte 73 # DW_AT_type
109 .byte 19 # DW_FORM_ref4
110 .byte 63 # DW_AT_external
111 .byte 25 # DW_FORM_flag_present
112 .byte 0 # EOM(1)
113 .byte 0 # EOM(2)
114 .byte 4 # Abbreviation Code
115 .byte 36 # DW_TAG_base_type
116 .byte 0 # DW_CHILDREN_no
117 .byte 3 # DW_AT_name
118 .byte 37 # DW_FORM_strx1
119 .byte 62 # DW_AT_encoding
120 .byte 11 # DW_FORM_data1
121 .byte 11 # DW_AT_byte_size
122 .byte 11 # DW_FORM_data1
123 .byte 0 # EOM(1)
124 .byte 0 # EOM(2)
125 .byte 0 # EOM(3)
126
127.section .debug_info,"",@progbits
128.Lcu_begin0:
129 .long 75 # Length of Unit
130 .short 5 # DWARF version number
131 .byte 1 # DWARF Unit Type
132 .byte 8 # Address Size (in bytes)
133 .long .debug_abbrev # Offset Into Abbrev. Section
134
135 .byte 1 # Abbrev [1] 0xc:0x43 DW_TAG_compile_unit
136 .byte 0 # DW_AT_producer
137 .short 4 # DW_AT_language
138 .byte 1 # DW_AT_name
139 .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
140 .long 0 # DW_AT_stmt_list
141 .byte 2 # DW_AT_comp_dir
142 .long .Laddr_table_base0 # DW_AT_addr_base
143 .quad 0 # DW_AT_low_pc
144 .byte 0 # DW_AT_ranges
145 .long .Lrnglists_table_base0 # DW_AT_rnglists_base
146
147 .byte 2 # Abbrev [2] 0x2b:0x10 DW_TAG_subprogram
148 .byte 0 # DW_AT_low_pc
149 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
150 .byte 1 # DW_AT_frame_base
151 .byte 86
152 .byte 3 # DW_AT_linkage_name
153 .byte 4 # DW_AT_name
154 .byte 1 # DW_AT_decl_file
155 .byte 1 # DW_AT_decl_line
156 .long 74 # DW_AT_type
157 # DW_AT_external
158
159 .byte 3 # Abbrev [3] 0x3b:0xf DW_TAG_subprogram
160 .byte 1 # DW_AT_low_pc
161 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
162 .byte 1 # DW_AT_frame_base
163 .byte 86
164 .byte 6 # DW_AT_name
165 .byte 1 # DW_AT_decl_file
166 .byte 5 # DW_AT_decl_line
167 .long 74 # DW_AT_type
168 # DW_AT_external
169
170 .byte 4 # Abbrev [4] 0x4a:0x4 DW_TAG_base_type
171 .byte 5 # DW_AT_name
172 .byte 5 # DW_AT_encoding
173 .byte 4 # DW_AT_byte_size
174 .byte 0 # End Of Children Mark
175
176.section .debug_rnglists,"",@progbits
177.long .Ldebug_rnglist_table_end0-.Ldebug_rnglist_table_start0 # Length
178.Ldebug_rnglist_table_start0:
179 .short 5 # Version
180 .byte 8 # Address size
181 .byte 0 # Segment selector size
182 .long 1 # Offset entry count
183.Lrnglists_table_base0:
184 .long .Ldebug_ranges0-.Lrnglists_table_base0
185.Ldebug_ranges0:
186 .byte 3 # DW_RLE_startx_length
187 .byte 0 # start index
188 .uleb128 .Lfunc_end0-.Lfunc_begin0 # length
189 .byte 3 # DW_RLE_startx_length
190 .byte 1 # start index
191 .uleb128 .Lfunc_end1-.Lfunc_begin1 # length
192 .byte 0 # DW_RLE_end_of_list
193.Ldebug_rnglist_table_end0:
194
195.section .debug_addr,"",@progbits
196 .long 20
197 .short 5
198 .byte 8
199 .byte 0
200.Laddr_table_base0:
201 .quad .Lfunc_begin0
202 .quad .Lfunc_begin1
deps/lld/test/ELF/gdb-index.s+1-1
...@@ -25,7 +25,7 @@...@@ -25,7 +25,7 @@
25# DISASM-CHECK: 201004: 90 nop25# DISASM-CHECK: 201004: 90 nop
26# DISASM-CHECK: 201005: 90 nop26# DISASM-CHECK: 201005: 90 nop
2727
28# DWARF: .gnu_index contents:28# DWARF: .gdb_index contents:
29# DWARF-NEXT: Version = 729# DWARF-NEXT: Version = 7
30# DWARF: CU list offset = 0x18, has 2 entries:30# DWARF: CU list offset = 0x18, has 2 entries:
31# DWARF-NEXT: 0: Offset = 0x0, Length = 0x3431# DWARF-NEXT: 0: Offset = 0x0, Length = 0x34
deps/lld/test/ELF/global-offset-table-position-redef-err.s created+14
...@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4
5# On some targets the location of the _GLOBAL_OFFSET_TABLE_ symbol table can
6# matter for the correctness of some relocations. Follow the example of ld.gold
7# and give a multiple definition error if input objects attempt to redefine it.
8
9# CHECK: ld.lld: error: {{.*o}} cannot redefine linker defined symbol '_GLOBAL_OFFSET_TABLE_'
10
11.data
12.global _GLOBAL_OFFSET_TABLE_
13_GLOBAL_OFFSET_TABLE_:
14.word 0
deps/lld/test/ELF/gnu-hash-table-copy.s+4-4
...@@ -13,10 +13,10 @@...@@ -13,10 +13,10 @@
1313
14# CHECK: Symbol table '.dynsym' contains 4 entries:14# CHECK: Symbol table '.dynsym' contains 4 entries:
15# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name15# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
16# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @16# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
17# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo@17# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo
18# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar@18# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar
19# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed@19# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed
2020
21# CHECK: First Hashed Symbol Index: 221# CHECK: First Hashed Symbol Index: 2
2222
deps/lld/test/ELF/gnu-hash-table-rwsegment.s+2-2
...@@ -8,8 +8,8 @@...@@ -8,8 +8,8 @@
8# CHECK-NEXT: Num Buckets: 18# CHECK-NEXT: Num Buckets: 1
9# CHECK-NEXT: First Hashed Symbol Index: 19# CHECK-NEXT: First Hashed Symbol Index: 1
10# CHECK-NEXT: Num Mask Words: 110# CHECK-NEXT: Num Mask Words: 1
11# CHECK-NEXT: Shift Count: 611# CHECK-NEXT: Shift Count: 26
12# CHECK-NEXT: Bloom Filter: [0x400000000004204]12# CHECK-NEXT: Bloom Filter: [0x400000000000204]
13# CHECK-NEXT: Buckets: [1]13# CHECK-NEXT: Buckets: [1]
14# CHECK-NEXT: Values: [0xB8860BA, 0xB887389]14# CHECK-NEXT: Values: [0xB8860BA, 0xB887389]
15# CHECK-NEXT: }15# CHECK-NEXT: }
deps/lld/test/ELF/gnu-hash-table.s+27-27
...@@ -13,7 +13,7 @@...@@ -13,7 +13,7 @@
13# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o13# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o
14# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t2.s -o %t2-ppc64.o14# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t2.s -o %t2-ppc64.o
1515
16# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a16# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a %t2-ppc64le.a
17# RUN: llvm-ar rc %t2-i386.a %t2-i386.o17# RUN: llvm-ar rc %t2-i386.a %t2-i386.o
18# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o18# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o
19# RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o19# RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o
...@@ -49,7 +49,7 @@...@@ -49,7 +49,7 @@
4949
50# EMPTY: DynamicSymbols [50# EMPTY: DynamicSymbols [
51# EMPTY: Symbol {51# EMPTY: Symbol {
52# EMPTY: Name: foo@52# EMPTY: Name: foo
53# EMPTY-NEXT: Value: 0x053# EMPTY-NEXT: Value: 0x0
54# EMPTY-NEXT: Size: 054# EMPTY-NEXT: Size: 0
55# EMPTY-NEXT: Binding: Global55# EMPTY-NEXT: Binding: Global
...@@ -62,7 +62,7 @@...@@ -62,7 +62,7 @@
62# EMPTY-NEXT: Num Buckets: 162# EMPTY-NEXT: Num Buckets: 1
63# EMPTY-NEXT: First Hashed Symbol Index: 263# EMPTY-NEXT: First Hashed Symbol Index: 2
64# EMPTY-NEXT: Num Mask Words: 164# EMPTY-NEXT: Num Mask Words: 1
65# EMPTY-NEXT: Shift Count: 665# EMPTY-NEXT: Shift Count: 26
66# EMPTY-NEXT: Bloom Filter: [0x0]66# EMPTY-NEXT: Bloom Filter: [0x0]
67# EMPTY-NEXT: Buckets: [0]67# EMPTY-NEXT: Buckets: [0]
68# EMPTY-NEXT: Values: []68# EMPTY-NEXT: Values: []
...@@ -87,32 +87,32 @@...@@ -87,32 +87,32 @@
87# I386: ]87# I386: ]
88# I386: DynamicSymbols [88# I386: DynamicSymbols [
89# I386: Symbol {89# I386: Symbol {
90# I386: Name: @90# I386: Name:
91# I386: Binding: Local91# I386: Binding: Local
92# I386: Section: Undefined92# I386: Section: Undefined
93# I386: }93# I386: }
94# I386: Symbol {94# I386: Symbol {
95# I386: Name: baz@95# I386: Name: baz
96# I386: Binding: Global96# I386: Binding: Global
97# I386: Section: Undefined97# I386: Section: Undefined
98# I386: }98# I386: }
99# I386: Symbol {99# I386: Symbol {
100# I386: Name: xyz@100# I386: Name: xyz
101# I386: Binding: Global101# I386: Binding: Global
102# I386: Section: Undefined102# I386: Section: Undefined
103# I386: }103# I386: }
104# I386: Symbol {104# I386: Symbol {
105# I386: Name: zed@105# I386: Name: zed
106# I386: Binding: Weak106# I386: Binding: Weak
107# I386: Section: Undefined107# I386: Section: Undefined
108# I386: }108# I386: }
109# I386: Symbol {109# I386: Symbol {
110# I386: Name: bar@110# I386: Name: bar
111# I386: Binding: Global111# I386: Binding: Global
112# I386: Section: .text112# I386: Section: .text
113# I386: }113# I386: }
114# I386: Symbol {114# I386: Symbol {
115# I386: Name: foo@115# I386: Name: foo
116# I386: Binding: Global116# I386: Binding: Global
117# I386: Section: .text117# I386: Section: .text
118# I386: }118# I386: }
...@@ -121,8 +121,8 @@...@@ -121,8 +121,8 @@
121# I386-NEXT: Num Buckets: 1121# I386-NEXT: Num Buckets: 1
122# I386-NEXT: First Hashed Symbol Index: 4122# I386-NEXT: First Hashed Symbol Index: 4
123# I386-NEXT: Num Mask Words: 1123# I386-NEXT: Num Mask Words: 1
124# I386-NEXT: Shift Count: 6124# I386-NEXT: Shift Count: 26
125# I386-NEXT: Bloom Filter: [0x4004204]125# I386-NEXT: Bloom Filter: [0x4000204]
126# I386-NEXT: Buckets: [4]126# I386-NEXT: Buckets: [4]
127# I386-NEXT: Values: [0xB8860BA, 0xB887389]127# I386-NEXT: Values: [0xB8860BA, 0xB887389]
128# I386-NEXT: }128# I386-NEXT: }
...@@ -147,32 +147,32 @@...@@ -147,32 +147,32 @@
147# X86_64: ]147# X86_64: ]
148# X86_64: DynamicSymbols [148# X86_64: DynamicSymbols [
149# X86_64: Symbol {149# X86_64: Symbol {
150# X86_64: Name: @150# X86_64: Name:
151# X86_64: Binding: Local151# X86_64: Binding: Local
152# X86_64: Section: Undefined152# X86_64: Section: Undefined
153# X86_64: }153# X86_64: }
154# X86_64: Symbol {154# X86_64: Symbol {
155# X86_64: Name: baz@155# X86_64: Name: baz
156# X86_64: Binding: Global156# X86_64: Binding: Global
157# X86_64: Section: Undefined157# X86_64: Section: Undefined
158# X86_64: }158# X86_64: }
159# X86_64: Symbol {159# X86_64: Symbol {
160# X86_64: Name: xyz@160# X86_64: Name: xyz
161# X86_64: Binding: Global161# X86_64: Binding: Global
162# X86_64: Section: Undefined162# X86_64: Section: Undefined
163# X86_64: }163# X86_64: }
164# X86_64: Symbol {164# X86_64: Symbol {
165# X86_64: Name: zed@165# X86_64: Name: zed
166# X86_64: Binding: Weak166# X86_64: Binding: Weak
167# X86_64: Section: Undefined167# X86_64: Section: Undefined
168# X86_64: }168# X86_64: }
169# X86_64: Symbol {169# X86_64: Symbol {
170# X86_64: Name: bar@170# X86_64: Name: bar
171# X86_64: Binding: Global171# X86_64: Binding: Global
172# X86_64: Section: .text172# X86_64: Section: .text
173# X86_64: }173# X86_64: }
174# X86_64: Symbol {174# X86_64: Symbol {
175# X86_64: Name: foo@175# X86_64: Name: foo
176# X86_64: Binding: Global176# X86_64: Binding: Global
177# X86_64: Section: .text177# X86_64: Section: .text
178# X86_64: }178# X86_64: }
...@@ -181,8 +181,8 @@...@@ -181,8 +181,8 @@
181# X86_64-NEXT: Num Buckets: 1181# X86_64-NEXT: Num Buckets: 1
182# X86_64-NEXT: First Hashed Symbol Index: 4182# X86_64-NEXT: First Hashed Symbol Index: 4
183# X86_64-NEXT: Num Mask Words: 1183# X86_64-NEXT: Num Mask Words: 1
184# X86_64-NEXT: Shift Count: 6184# X86_64-NEXT: Shift Count: 26
185# X86_64-NEXT: Bloom Filter: [0x400000000004204]185# X86_64-NEXT: Bloom Filter: [0x400000000000204]
186# X86_64-NEXT: Buckets: [4]186# X86_64-NEXT: Buckets: [4]
187# X86_64-NEXT: Values: [0xB8860BA, 0xB887389]187# X86_64-NEXT: Values: [0xB8860BA, 0xB887389]
188# X86_64-NEXT: }188# X86_64-NEXT: }
...@@ -207,32 +207,32 @@...@@ -207,32 +207,32 @@
207# PPC64: ]207# PPC64: ]
208# PPC64: DynamicSymbols [208# PPC64: DynamicSymbols [
209# PPC64: Symbol {209# PPC64: Symbol {
210# PPC64: Name: @210# PPC64: Name:
211# PPC64: Binding: Local211# PPC64: Binding: Local
212# PPC64: Section: Undefined212# PPC64: Section: Undefined
213# PPC64: }213# PPC64: }
214# PPC64: Symbol {214# PPC64: Symbol {
215# PPC64: Name: baz@215# PPC64: Name: baz
216# PPC64: Binding: Global216# PPC64: Binding: Global
217# PPC64: Section: Undefined217# PPC64: Section: Undefined
218# PPC64: }218# PPC64: }
219# PPC64: Symbol {219# PPC64: Symbol {
220# PPC64: Name: xyz@220# PPC64: Name: xyz
221# PPC64: Binding: Global221# PPC64: Binding: Global
222# PPC64: Section: Undefined222# PPC64: Section: Undefined
223# PPC64: }223# PPC64: }
224# PPC64: Symbol {224# PPC64: Symbol {
225# PPC64: Name: zed@225# PPC64: Name: zed
226# PPC64: Binding: Weak226# PPC64: Binding: Weak
227# PPC64: Section: Undefined227# PPC64: Section: Undefined
228# PPC64: }228# PPC64: }
229# PPC64: Symbol {229# PPC64: Symbol {
230# PPC64: Name: bar@230# PPC64: Name: bar
231# PPC64: Binding: Global231# PPC64: Binding: Global
232# PPC64: Section: .text232# PPC64: Section: .text
233# PPC64: }233# PPC64: }
234# PPC64: Symbol {234# PPC64: Symbol {
235# PPC64: Name: foo@235# PPC64: Name: foo
236# PPC64: Binding: Global236# PPC64: Binding: Global
237# PPC64: Section: .text237# PPC64: Section: .text
238# PPC64: }238# PPC64: }
...@@ -241,8 +241,8 @@...@@ -241,8 +241,8 @@
241# PPC64-NEXT: Num Buckets: 1241# PPC64-NEXT: Num Buckets: 1
242# PPC64-NEXT: First Hashed Symbol Index: 4242# PPC64-NEXT: First Hashed Symbol Index: 4
243# PPC64-NEXT: Num Mask Words: 1243# PPC64-NEXT: Num Mask Words: 1
244# PPC64-NEXT: Shift Count: 6244# PPC64-NEXT: Shift Count: 26
245# PPC64-NEXT: Bloom Filter: [0x400000000004204]245# PPC64-NEXT: Bloom Filter: [0x400000000000204]
246# PPC64-NEXT: Buckets: [4]246# PPC64-NEXT: Buckets: [4]
247# PPC64-NEXT: Values: [0xB8860BA, 0xB887389]247# PPC64-NEXT: Values: [0xB8860BA, 0xB887389]
248# PPC64-NEXT: }248# PPC64-NEXT: }
deps/lld/test/ELF/gnu-ifunc-empty.s created+16
...@@ -0,0 +1,16 @@
1// REQUIRES: x86
2
3// Verifies that .rela_iplt_{start,end} point to a dummy section
4// if .rela.iplt does not exist.
5
6// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
7// RUN: ld.lld -static %t.o -o %t.exe
8// RUN: llvm-objdump -syms %t.exe | FileCheck %s
9
10// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_end
11// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_start
12
13.globl _start
14_start:
15 movl $__rela_iplt_start, %edx
16 movl $__rela_iplt_end, %edx
deps/lld/test/ELF/gnu-ifunc-i386.s+19-19
...@@ -16,14 +16,14 @@...@@ -16,14 +16,14 @@
16// CHECK-NEXT: Offset: 0xD416// CHECK-NEXT: Offset: 0xD4
17// CHECK-NEXT: Size: 1617// CHECK-NEXT: Size: 16
18// CHECK-NEXT: Link: 018// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 019// CHECK-NEXT: Info: 4
20// CHECK-NEXT: AddressAlignment: 420// CHECK-NEXT: AddressAlignment: 4
21// CHECK-NEXT: EntrySize: 821// CHECK-NEXT: EntrySize: 8
22// CHECK-NEXT: }22// CHECK-NEXT: }
23// CHECK: Relocations [23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rel.plt {24// CHECK-NEXT: Section ({{.*}}) .rel.plt {
25// CHECK-NEXT: 0x12000 R_386_IRELATIVE25// CHECK-NEXT: 0x402000 R_386_IRELATIVE
26// CHECK-NEXT: 0x12004 R_386_IRELATIVE26// CHECK-NEXT: 0x402004 R_386_IRELATIVE
27// CHECK-NEXT: }27// CHECK-NEXT: }
28// CHECK-NEXT: ]28// CHECK-NEXT: ]
2929
...@@ -39,7 +39,7 @@...@@ -39,7 +39,7 @@
39// CHECK-NEXT: }39// CHECK-NEXT: }
40// CHECK-NEXT: Symbol {40// CHECK-NEXT: Symbol {
41// CHECK-NEXT: Name: __rel_iplt_end41// CHECK-NEXT: Name: __rel_iplt_end
42// CHECK-NEXT: Value: 0x100E442// CHECK-NEXT: Value: 0x4000E4
43// CHECK-NEXT: Size: 043// CHECK-NEXT: Size: 0
44// CHECK-NEXT: Binding: Local44// CHECK-NEXT: Binding: Local
45// CHECK-NEXT: Type: None45// CHECK-NEXT: Type: None
...@@ -61,7 +61,7 @@...@@ -61,7 +61,7 @@
61// CHECK-NEXT: }61// CHECK-NEXT: }
62// CHECK-NEXT: Symbol {62// CHECK-NEXT: Symbol {
63// CHECK-NEXT: Name: _start63// CHECK-NEXT: Name: _start
64// CHECK-NEXT: Value: 0x1100264// CHECK-NEXT: Value: 0x401002
65// CHECK-NEXT: Size: 065// CHECK-NEXT: Size: 0
66// CHECK-NEXT: Binding: Global66// CHECK-NEXT: Binding: Global
67// CHECK-NEXT: Type: None67// CHECK-NEXT: Type: None
...@@ -70,7 +70,7 @@...@@ -70,7 +70,7 @@
70// CHECK-NEXT: }70// CHECK-NEXT: }
71// CHECK-NEXT: Symbol {71// CHECK-NEXT: Symbol {
72// CHECK-NEXT: Name: bar72// CHECK-NEXT: Name: bar
73// CHECK-NEXT: Value: 0x1100173// CHECK-NEXT: Value: 0x401001
74// CHECK-NEXT: Size: 074// CHECK-NEXT: Size: 0
75// CHECK-NEXT: Binding: Global75// CHECK-NEXT: Binding: Global
76// CHECK-NEXT: Type: GNU_IFunc76// CHECK-NEXT: Type: GNU_IFunc
...@@ -79,7 +79,7 @@...@@ -79,7 +79,7 @@
79// CHECK-NEXT: }79// CHECK-NEXT: }
80// CHECK-NEXT: Symbol {80// CHECK-NEXT: Symbol {
81// CHECK-NEXT: Name: foo81// CHECK-NEXT: Name: foo
82// CHECK-NEXT: Value: 0x1100082// CHECK-NEXT: Value: 0x401000
83// CHECK-NEXT: Size: 083// CHECK-NEXT: Size: 0
84// CHECK-NEXT: Binding: Global84// CHECK-NEXT: Binding: Global
85// CHECK-NEXT: Type: GNU_IFunc85// CHECK-NEXT: Type: GNU_IFunc
...@@ -90,22 +90,22 @@...@@ -90,22 +90,22 @@
9090
91// DISASM: Disassembly of section .text:91// DISASM: Disassembly of section .text:
92// DISASM-NEXT: foo:92// DISASM-NEXT: foo:
93// DISASM-NEXT: 11000: c3 retl93// DISASM-NEXT: 401000: c3 retl
94// DISASM: bar:94// DISASM: bar:
95// DISASM-NEXT: 11001: c3 retl95// DISASM-NEXT: 401001: c3 retl
96// DISASM: _start:96// DISASM: _start:
97// DISASM-NEXT: 11002: e8 19 00 00 00 calll 2597// DISASM-NEXT: 401002: e8 19 00 00 00 calll 25
98// DISASM-NEXT: 11007: e8 24 00 00 00 calll 3698// DISASM-NEXT: 401007: e8 24 00 00 00 calll 36
99// DISASM-NEXT: 1100c: ba d4 00 01 00 movl $65748, %edx99// DISASM-NEXT: 40100c: ba d4 00 40 00 movl $4194516, %edx
100// DISASM-NEXT: 11011: ba e4 00 01 00 movl $65764, %edx100// DISASM-NEXT: 401011: ba e4 00 40 00 movl $4194532, %edx
101// DISASM-NEXT: Disassembly of section .plt:101// DISASM-NEXT: Disassembly of section .plt:
102// DISASM-NEXT: .plt:102// DISASM-NEXT: .plt:
103// DISASM-NEXT: 11020: ff 25 00 20 01 00 jmpl *73728103// DISASM-NEXT: 401020: ff 25 00 20 40 00 jmpl *4202496
104// DISASM-NEXT: 11026: 68 10 00 00 00 pushl $16104// DISASM-NEXT: 401026: 68 10 00 00 00 pushl $16
105// DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xe>105// DISASM-NEXT: 40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
106// DISASM-NEXT: 11030: ff 25 04 20 01 00 jmpl *73732106// DISASM-NEXT: 401030: ff 25 04 20 40 00 jmpl *4202500
107// DISASM-NEXT: 11036: 68 18 00 00 00 pushl $24107// DISASM-NEXT: 401036: 68 18 00 00 00 pushl $24
108// DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xe>108// DISASM-NEXT: 40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
109109
110.text110.text
111.type foo STT_GNU_IFUNC111.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-plt-i386.s+34-30
...@@ -10,16 +10,16 @@...@@ -10,16 +10,16 @@
10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
11// CHECK: Relocations [11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rel.plt {12// CHECK-NEXT: Section (4) .rel.plt {
13// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar213// CHECK-NEXT: 0x40200C R_386_JUMP_SLOT bar2
14// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed214// CHECK-NEXT: 0x402010 R_386_JUMP_SLOT zed2
15// CHECK-NEXT: 0x12014 R_386_IRELATIVE15// CHECK-NEXT: 0x402014 R_386_IRELATIVE
16// CHECK-NEXT: 0x12018 R_386_IRELATIVE16// CHECK-NEXT: 0x402018 R_386_IRELATIVE
1717
18// Check that IRELATIVE .got.plt entries point to ifunc resolver and not18// Check that IRELATIVE .got.plt entries point to ifunc resolver and not
19// back to the plt entry + 6.19// back to the plt entry + 6.
20// GOTPLT: Contents of section .got.plt:20// GOTPLT: Contents of section .got.plt:
21// GOTPLT: 12000 00300100 00000000 00000000 3610010021// GOTPLT: 402000 00304000 00000000 00000000 36104000
22// GOTPLT-NEXT: 12010 46100100 00100100 0110010022// GOTPLT-NEXT: 402010 46104000 00104000 01104000
2323
24// Check that the PLTRELSZ tag includes the IRELATIVE relocations24// Check that the PLTRELSZ tag includes the IRELATIVE relocations
25// CHECK: DynamicSection [25// CHECK: DynamicSection [
...@@ -28,34 +28,38 @@...@@ -28,34 +28,38 @@
28// Check that a PLT header is written and the ifunc entries appear last28// Check that a PLT header is written and the ifunc entries appear last
29// DISASM: Disassembly of section .text:29// DISASM: Disassembly of section .text:
30// DISASM-NEXT: foo:30// DISASM-NEXT: foo:
31// DISASM-NEXT: 11000: c3 retl31// DISASM-NEXT: 401000: c3 retl
32// DISASM: bar:32// DISASM: bar:
33// DISASM-NEXT: 11001: c3 retl33// DISASM-NEXT: 401001: c3 retl
34// DISASM: _start:34// DISASM: _start:
35// DISASM-NEXT: 11002: e8 49 00 00 00 calll 7335// DISASM-NEXT: 401002: e8 49 00 00 00 calll 73
36// DISASM-NEXT: 11007: e8 54 00 00 00 calll 8436// DISASM-NEXT: 401007: e8 54 00 00 00 calll 84
37// DISASM-NEXT: 1100c: e8 1f 00 00 00 calll 3137// DISASM-NEXT: 40100c: e8 1f 00 00 00 calll 31
38// DISASM-NEXT: 11011: e8 2a 00 00 00 calll 4238// DISASM-NEXT: 401011: e8 2a 00 00 00 calll 42
39// DISASM-NEXT: Disassembly of section .plt:39// DISASM-NEXT: Disassembly of section .plt:
40// DISASM-NEXT: .plt:40// DISASM-NEXT: .plt:
41// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 7373241// DISASM-NEXT: 401020: ff 35 04 20 40 00 pushl 4202500
42// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *7373642// DISASM-NEXT: 401026: ff 25 08 20 40 00 jmpl *4202504
43// DISASM-NEXT: 1102c: 90 nop43// DISASM-NEXT: 40102c: 90 nop
44// DISASM-NEXT: 1102d: 90 nop44// DISASM-NEXT: 40102d: 90 nop
45// DISASM-NEXT: 1102e: 90 nop45// DISASM-NEXT: 40102e: 90 nop
46// DISASM-NEXT: 1102f: 90 nop46// DISASM-NEXT: 40102f: 90 nop
47// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *7374047// DISASM-EMPTY:
48// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $048// DISASM-NEXT: bar2@plt:
49// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>49// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
50// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *7374450// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
51// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $851// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.plt>
52// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>52// DISASM-EMPTY:
53// DISASM-NEXT: 11050: ff 25 14 20 01 00 jmpl *7374853// DISASM-NEXT: zed2@plt:
54// DISASM-NEXT: 11056: 68 30 00 00 00 pushl $4854// DISASM-NEXT: 401040: ff 25 10 20 40 00 jmpl *4202512
55// DISASM-NEXT: 1105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>55// DISASM-NEXT: 401046: 68 08 00 00 00 pushl $8
56// DISASM-NEXT: 11060: ff 25 18 20 01 00 jmpl *7375256// DISASM-NEXT: 40104b: e9 d0 ff ff ff jmp -48 <.plt>
57// DISASM-NEXT: 11066: 68 38 00 00 00 pushl $5657// DISASM-NEXT: 401050: ff 25 14 20 40 00 jmpl *4202516
58// DISASM-NEXT: 1106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>58// DISASM-NEXT: 401056: 68 30 00 00 00 pushl $48
59// DISASM-NEXT: 40105b: e9 e0 ff ff ff jmp -32 <zed2@plt>
60// DISASM-NEXT: 401060: ff 25 18 20 40 00 jmpl *4202520
61// DISASM-NEXT: 401066: 68 38 00 00 00 pushl $56
62// DISASM-NEXT: 40106b: e9 d0 ff ff ff jmp -48 <zed2@plt>
5963
60.text64.text
61.type foo STT_GNU_IFUNC65.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-plt.s+6-2
...@@ -42,18 +42,22 @@...@@ -42,18 +42,22 @@
42// DISASM-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)42// DISASM-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
43// DISASM-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)43// DISASM-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
44// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)44// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
45// DISASM-EMPTY:
46// DISASM-NEXT: bar2@plt:
45// DISASM-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)47// DISASM-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
46// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $048// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $0
47// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>49// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
50// DISASM-EMPTY:
51// DISASM-NEXT: zed2@plt:
48// DISASM-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)52// DISASM-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
49// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $153// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $1
50// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>54// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
51// DISASM-NEXT: 201050: ff 25 d2 0f 00 00 jmpq *4050(%rip)55// DISASM-NEXT: 201050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
52// DISASM-NEXT: 201056: 68 00 00 00 00 pushq $056// DISASM-NEXT: 201056: 68 00 00 00 00 pushq $0
53// DISASM-NEXT: 20105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>57// DISASM-NEXT: 20105b: e9 e0 ff ff ff jmp -32 <zed2@plt>
54// DISASM-NEXT: 201060: ff 25 ca 0f 00 00 jmpq *4042(%rip)58// DISASM-NEXT: 201060: ff 25 ca 0f 00 00 jmpq *4042(%rip)
55// DISASM-NEXT: 201066: 68 01 00 00 00 pushq $159// DISASM-NEXT: 201066: 68 01 00 00 00 pushq $1
56// DISASM-NEXT: 20106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>60// DISASM-NEXT: 20106b: e9 d0 ff ff ff jmp -48 <zed2@plt>
5761
58.text62.text
59.type foo STT_GNU_IFUNC63.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-relative.s+9-7
...@@ -1,7 +1,9 @@...@@ -1,7 +1,9 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -static %t.o -o %tout3// RUN: ld.lld --strip-all %t.o -o %t
4// RUN: llvm-readobj -r -t %tout | FileCheck %s4// RUN: llvm-readobj -r %t | FileCheck %s
5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-readobj -r -t %t | FileCheck %s --check-prefixes=CHECK,SYM
57
6.type foo STT_GNU_IFUNC8.type foo STT_GNU_IFUNC
7.globl foo9.globl foo
...@@ -16,8 +18,8 @@ _start:...@@ -16,8 +18,8 @@ _start:
16// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]18// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]
17// CHECK-NEXT: }19// CHECK-NEXT: }
1820
19// CHECK: Name: foo21// SYM: Name: foo
20// CHECK-NEXT: Value: 0x[[ADDR]]22// SYM-NEXT: Value: 0x[[ADDR]]
21// CHECK-NEXT: Size: 023// SYM-NEXT: Size: 0
22// CHECK-NEXT: Binding: Global24// SYM-NEXT: Binding: Global
23// CHECK-NEXT: Type: GNU_IFunc25// SYM-NEXT: Type: GNU_IFunc
deps/lld/test/ELF/gnu-ifunc-shared.s+5-1
...@@ -23,15 +23,19 @@...@@ -23,15 +23,19 @@
23// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)23// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
24// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)24// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
25// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)25// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
26// DISASM-EMPTY:
27// DISASM-NEXT: fct2@plt:
26// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)28// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
27// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $029// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
28// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>30// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
31// DISASM-EMPTY:
32// DISASM-NEXT: f2@plt:
29// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)33// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
30// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $134// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
31// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>35// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
32// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)36// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
33// DISASM-NEXT: 1056: 68 00 00 00 00 pushq $037// DISASM-NEXT: 1056: 68 00 00 00 00 pushq $0
34// DISASM-NEXT: 105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>38// DISASM-NEXT: 105b: e9 e0 ff ff ff jmp -32 <f2@plt>
3539
36// CHECK: Relocations [40// CHECK: Relocations [
37// CHECK-NEXT: Section (4) .rela.plt {41// CHECK-NEXT: Section (4) .rela.plt {
deps/lld/test/ELF/gnu-ifunc.s+3-1
...@@ -16,10 +16,12 @@...@@ -16,10 +16,12 @@
16// CHECK-NEXT: Offset: 0x15816// CHECK-NEXT: Offset: 0x158
17// CHECK-NEXT: Size: 4817// CHECK-NEXT: Size: 48
18// CHECK-NEXT: Link: 018// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 019// CHECK-NEXT: Info: [[GOTPLT:.*]]
20// CHECK-NEXT: AddressAlignment: 820// CHECK-NEXT: AddressAlignment: 8
21// CHECK-NEXT: EntrySize: 2421// CHECK-NEXT: EntrySize: 24
22// CHECK-NEXT: }22// CHECK-NEXT: }
23// CHECK: Index: [[GOTPLT]]
24// CHECK-NEXT: Name: .got.plt
23// CHECK: Relocations [25// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rela.plt {26// CHECK-NEXT: Section ({{.*}}) .rela.plt {
25// CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE27// CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE
deps/lld/test/ELF/gnu-unique.s+2-2
...@@ -20,7 +20,7 @@ _start:...@@ -20,7 +20,7 @@ _start:
20.type symb, @gnu_unique_object20.type symb, @gnu_unique_object
21symb:21symb:
2222
23# GNU: Name: symb@23# GNU: Name: symb
24# GNU-NEXT: Value:24# GNU-NEXT: Value:
25# GNU-NEXT: Size: 025# GNU-NEXT: Size: 0
26# GNU-NEXT: Binding: Unique26# GNU-NEXT: Binding: Unique
...@@ -29,7 +29,7 @@ symb:...@@ -29,7 +29,7 @@ symb:
29# GNU-NEXT: Section: .data29# GNU-NEXT: Section: .data
30# GNU-NEXT: }30# GNU-NEXT: }
3131
32# NO: Name: symb@32# NO: Name: symb
33# NO-NEXT: Value:33# NO-NEXT: Value:
34# NO-NEXT: Size: 034# NO-NEXT: Size: 0
35# NO-NEXT: Binding: Global35# NO-NEXT: Binding: Global
deps/lld/test/ELF/got-i386.s+9-9
...@@ -10,7 +10,7 @@...@@ -10,7 +10,7 @@
10// CHECK-NEXT: SHF_ALLOC10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x1200013// CHECK-NEXT: Address: 0x402000
14// CHECK-NEXT: Offset:14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 015// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Link:16// CHECK-NEXT: Link:
...@@ -19,7 +19,7 @@...@@ -19,7 +19,7 @@
1919
20// CHECK: Symbol {20// CHECK: Symbol {
21// CHECK: Name: bar21// CHECK: Name: bar
22// CHECK-NEXT: Value: 0x1200022// CHECK-NEXT: Value: 0x402000
23// CHECK-NEXT: Size: 1023// CHECK-NEXT: Size: 10
24// CHECK-NEXT: Binding: Global24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Object25// CHECK-NEXT: Type: Object
...@@ -28,7 +28,7 @@...@@ -28,7 +28,7 @@
28// CHECK-NEXT: }28// CHECK-NEXT: }
29// CHECK-NEXT: Symbol {29// CHECK-NEXT: Symbol {
30// CHECK-NEXT: Name: obj30// CHECK-NEXT: Name: obj
31// CHECK-NEXT: Value: 0x1200A31// CHECK-NEXT: Value: 0x40200A
32// CHECK-NEXT: Size: 1032// CHECK-NEXT: Size: 10
33// CHECK-NEXT: Binding: Global33// CHECK-NEXT: Binding: Global
34// CHECK-NEXT: Type: Object34// CHECK-NEXT: Type: Object
...@@ -36,14 +36,14 @@...@@ -36,14 +36,14 @@
36// CHECK-NEXT: Section: .bss36// CHECK-NEXT: Section: .bss
37// CHECK-NEXT: }37// CHECK-NEXT: }
3838
39// 0x12000 - 0 = addr(.got) = 0x1200039// 0x402000 - 0 = addr(.got) = 0x402000
40// 0x1200A - 10 = addr(.got) = 0x1200040// 0x40200A - 10 = addr(.got) = 0x402000
41// 0x1200A + 5 - 15 = addr(.got) = 0x1200041// 0x40200A + 5 - 15 = addr(.got) = 0x402000
42// DISASM: Disassembly of section .text:42// DISASM: Disassembly of section .text:
43// DISASM-NEXT: _start:43// DISASM-NEXT: _start:
44// DISASM-NEXT: 11000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)44// DISASM-NEXT: 401000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)
45// DISASM-NEXT: 1100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)45// DISASM-NEXT: 40100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)
46// DISASM-NEXT: 11014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)46// DISASM-NEXT: 401014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
4747
48.global _start48.global _start
49_start:49_start:
deps/lld/test/ELF/got32-i386-pie-rw.s+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o2# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readelf -r -s %t | FileCheck %s4# RUN: llvm-readelf -r -S %t | FileCheck %s
55
6# Unlike bfd and gold we accept this.6# Unlike bfd and gold we accept this.
77
deps/lld/test/ELF/got32-i386.s+2-2
...@@ -14,10 +14,10 @@ _start:...@@ -14,10 +14,10 @@ _start:
1414
15## 73728 == 0x12000 == ADDR(.got)15## 73728 == 0x12000 == ADDR(.got)
16# CHECK: _start:16# CHECK: _start:
17# CHECK-NEXT: 11001: 8b 1d {{.*}} movl 73728, %ebx17# CHECK-NEXT: 401001: 8b 1d {{.*}} movl 4202496, %ebx
18# CHECK: Sections:18# CHECK: Sections:
19# CHECK: Name Size Address19# CHECK: Name Size Address
20# CHECK: .got 00000004 000000000001200020# CHECK: .got 00000004 0000000000402000
2121
22# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR22# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
23# ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output23# ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
deps/lld/test/ELF/got32x-i386.s+5-5
...@@ -33,13 +33,13 @@...@@ -33,13 +33,13 @@
3333
34## 73728 == 0x12000 == ADDR(.got)34## 73728 == 0x12000 == ADDR(.got)
35# CHECK: _start:35# CHECK: _start:
36# CHECK-NEXT: 11001: 8b 05 {{.*}} movl 77824, %eax36# CHECK-NEXT: 401001: 8b 05 {{.*}} movl 4206592, %eax
37# CHECK-NEXT: 11007: 8b 1d {{.*}} movl 77824, %ebx37# CHECK-NEXT: 401007: 8b 1d {{.*}} movl 4206592, %ebx
38# CHECK-NEXT: 1100d: 8b 80 {{.*}} movl -4(%eax), %eax38# CHECK-NEXT: 40100d: 8b 80 {{.*}} movl -4(%eax), %eax
39# CHECK-NEXT: 11013: 8b 83 {{.*}} movl -4(%ebx), %eax39# CHECK-NEXT: 401013: 8b 83 {{.*}} movl -4(%ebx), %eax
40# CHECK: Sections:40# CHECK: Sections:
41# CHECK: Name Size Address41# CHECK: Name Size Address
42# CHECK: .got 00000004 000000000001300042# CHECK: .got 00000004 0000000000403000
4343
44# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \44# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
45# RUN: FileCheck %s --check-prefix=ERR45# RUN: FileCheck %s --check-prefix=ERR
deps/lld/test/ELF/hexagon-eflag.s created+7
...@@ -0,0 +1,7 @@
1# REQUIRES: hexagon
2# RUN: llvm-mc -filetype=obj -mv62 -triple=hexagon-unknown-elf %s -o %t
3# RUN: llvm-mc -filetype=obj -mv60 -triple=hexagon-unknown-elf %S/Inputs/hexagon.s -o %t2
4# RUN: ld.lld %t2 %t -o %t3
5# RUN: llvm-readelf -h %t3 | FileCheck %s
6# Verify that the largest arch in the input list is selected.
7# CHECK: Flags: 0x62
deps/lld/test/ELF/hexagon-shared.s created+46
...@@ -0,0 +1,46 @@
1# REQUIRES: hexagon
2# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t
3# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %S/Inputs/hexagon-shared.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -soname %t3.so -o %t3.so
5# RUN: ld.lld -shared %t %t3.so -soname %t4.so -o %t4.so
6# RUN: llvm-objdump -d -j .plt %t4.so | FileCheck --check-prefix=PLT %s
7# RUN: llvm-objdump -d -j .text %t4.so | FileCheck --check-prefix=TEXT %s
8# RUN: llvm-objdump -D -j .got %t4.so | FileCheck --check-prefix=GOT %s
9
10.global foo
11foo:
12
13# _HEX_32_PCREL
14.word _DYNAMIC - .
15call ##bar
16
17# R_HEX_PLT_B22_PCREL
18call bar@PLT
19
20# R_HEX_GOT_11_X and R_HEX_GOT_32_6_X
21r2=add(pc,##_GLOBAL_OFFSET_TABLE_@PCREL)
22r0 = memw (r2+##bar@GOT)
23jumpr r0
24
25# R_HEX_GOT_16_X
26r0 = add(r1,##bar@GOT)
27
28# PLT: { immext(#65472
29# PLT: r28 = add(pc,##65488) }
30# PLT: { r14 -= add(r28,#16)
31# PLT: r15 = memw(r28+#8)
32# PLT: r28 = memw(r28+#4) }
33# PLT: { r14 = asr(r14,#2)
34# PLT: jumpr r28 }
35# PLT: { trap0(#219) }
36# PLT: immext(#65472)
37# PLT: r14 = add(pc,##65472) }
38# PLT: r28 = memw(r14+#0) }
39# PLT: jumpr r28 }
40
41# TEXT: 10000: 00 00 02 00 00020000
42# TEXT: { call 0x10050 }
43# TEXT: r0 = add(r1,##65664) }
44
45# GOT: .got:
46# GOT: 30080: 00 00 00 00 00000000 <unknown>
deps/lld/test/ELF/hexagon.s+199-7
...@@ -4,28 +4,220 @@...@@ -4,28 +4,220 @@
4# RUN: ld.lld %t2 %t -o %t34# RUN: ld.lld %t2 %t -o %t3
5# RUN: llvm-objdump -d %t3 | FileCheck %s5# RUN: llvm-objdump -d %t3 | FileCheck %s
66
7# Note: 69632 == 0x110007# Note: 131072 == 0x20000
8# R_HEX_32_6_X8# R_HEX_32_6_X
9# R_HEX_12_X9# R_HEX_12_X
10if (p0) r0 = ##_start10if (p0) r0 = ##_start
11# CHECK: immext(#69632)11# CHECK: immext(#131072)
12# CHECK: if (p0) r0 = ##6963212# CHECK: if (p0) r0 = ##131072
1313
14# R_HEX_B15_PCREL14# R_HEX_B15_PCREL
15if (p0) jump:nt #_start15if (p0) jump:nt #_start
16# CHECK: if (p0) jump:nt 0x1100016# CHECK: if (p0) jump:nt 0x20000
1717
18# R_HEX_B32_PCREL_X18# R_HEX_B32_PCREL_X
19# R_HEX_B15_PCREL_X19# R_HEX_B15_PCREL_X
20if (p0) jump:nt ##_start20if (p0) jump:nt ##_start
21# CHECK: if (p0) jump:nt 0x1100021# CHECK: if (p0) jump:nt 0x20000
2222
23# R_HEX_B22_PCREL23# R_HEX_B22_PCREL
24call #_start24call #_start
25# CHECK: call 0x1100025# CHECK: call 0x20000
2626
27# R_HEX_B32_PCREL_X27# R_HEX_B32_PCREL_X
28# R_HEX_B22_PCREL_X28# R_HEX_B22_PCREL_X
29call ##_start29call ##_start
30# CHECK: immext(#4294967232)30# CHECK: immext(#4294967232)
31# CHECK: call 0x1100031# CHECK: call 0x20000
32
33# R_HEX_6_X tests:
34# One test for each mask in the lookup table.
35
36#0x38000000
37if (!P0) memw(r0+#8)=##_start
38# CHECK: 38c0c100 if (!p0) memw(r0+#8) = ##131072 }
39
40#0x39000000
41{ p0 = p1
42 if (!P0.new) memw(r0+#0)=##_start }
43# CHECK: 39c0c000 if (!p0.new) memw(r0+#0) = ##131072 }
44
45#0x3e000000
46memw(r0+##_start)+=r1
47# CHECK: 3e40c001 memw(r0+##131072) += r1 }
48
49#0x3f000000
50memw(r0+##_start)+=#4
51# CHECK: 3f40c004 memw(r0+##131072) += #4 }
52
53#0x40000000
54{ r0 = r1
55 if (p0) memb(r0+##_start)=r0.new }
56# CHECK: 40a0c200 if (p0) memb(r0+##131072) = r0.new }
57
58#0x41000000
59if (p0) r0=memb(r1+##_start)
60# CHECK: 4101c000 if (p0) r0 = memb(r1+##131072) }
61
62#0x42000000
63{ r0 = r1
64 p0 = p1
65 if (p0.new) memb(r0+##_start)=r0.new }
66# CHECK: 42a0c200 if (p0.new) memb(r0+##131072) = r0.new }
67
68#0x43000000
69{ p0 = p1
70 if (P0.new) r0=memb(r0+##_start) }
71# CHECK: 4300c000 if (p0.new) r0 = memb(r0+##131072) }
72
73#0x44000000
74if (!p0) memb(r0+##_start)=r1
75# CHECK: 4400c100 if (!p0) memb(r0+##131072) = r1 }
76
77#0x45000000
78if (!p0) r0=memb(r1+##_start)
79# CHECK: 4501c000 if (!p0) r0 = memb(r1+##131072) }
80
81#0x46000000
82{ p0 = p1
83 if (!p0.new) memb(r0+##_start)=r1 }
84# CHECK: 4600c100 if (!p0.new) memb(r0+##131072) = r1 }
85
86#0x47000000
87{ p0 = p1
88 if (!p0.new) r0=memb(r1+##_start) }
89# CHECK: 4701c000 if (!p0.new) r0 = memb(r1+##131072) }
90
91#0x6a000000 -- Note 4294967132 == -0xa4 the distance between
92# here and _start, so this will change if
93# tests are added between here and _start
94r0=add(pc,##_start@pcrel)
95# CHECK: 6a49ce00 r0 = add(pc,##4294967132) }
96
97#0x7c000000
98r1:0=combine(#8,##_start)
99# CHECK: 7c80c100 r1:0 = combine(#8,##131072) }
100
101#0x9a000000
102r1:0=memb_fifo(r2=##_start)
103# CHECK: 9a82d000 r1:0 = memb_fifo(r2=##131072) }
104
105#0x9b000000
106r0=memb(r1=##_start)
107# CHECK: 9b01d000 r0 = memb(r1=##131072) }
108
109#0x9c000000
110r1:0=memb_fifo(r2<<#2+##_start)
111# CHECK: 9c82f000 r1:0 = memb_fifo(r2<<#2+##131072) }
112
113#0x9d000000
114r0=memb(r1<<#2+##_start)
115# CHECK: 9d01f000 r0 = memb(r1<<#2+##131072) }
116
117#0x9f000000
118if (!p0) r0=memb(##_start)
119# CHECK: 9f00e880 if (!p0) r0 = memb(##131072) }
120
121#0xab000000
122memb(r0=##_start)=r1
123# CHECK: ab00c180 memb(r0=##131072) = r1 }
124
125#0xad000000
126memb(r0<<#2+##_start)=r1
127# CHECK: ad00e180 memb(r0<<#2+##131072) = r1 }
128
129#0xaf000000
130if (!p0) memb(##_start)=r1
131# CHECK: af00c184 if (!p0) memb(##131072) = r1 }
132
133#0xd7000000
134r0=add(##_start,mpyi(r1,r2))
135# CHECK: d701c200 r0 = add(##131072,mpyi(r1,r2)) }
136
137#0xd8000000
138R0=add(##_start,mpyi(r0,#2))
139# CHECK: d800c002 r0 = add(##131072,mpyi(r0,#2)) }
140
141#0xdb000000
142r0=add(r1,add(r2,##_start))
143# CHECK: db01c002 r0 = add(r1,add(r2,##131072)) }
144
145#0xdf000000
146r0=add(r1,mpyi(r2,##_start))
147# CHECK: df82c001 r0 = add(r1,mpyi(r2,##131072)) }
148
149# Duplex form of R_HEX_6_X
150# R_HEX_32_6_X
151# R_HEX_6_X
152{ r0 = ##_start; r2 = r16 }
153# CHECK: 28003082 r0 = ##131072; r2 = r16 }
154
155# R_HEX_HI16
156r0.h = #HI(_start)
157# CHECK: r0.h = #2
158
159# R_HEX_LO16
160r0.l = #LO(_start)
161# CHECK: r0.l = #0
162
163# R_HEX_8_X has 3 relocation mask variations
164#0xde000000
165r0=sub(##_start, asl(r0, #1))
166# CHECK: de00c106 r0 = sub(##131072,asl(r0,#1)) }
167
168#0x3c000000
169memw(r0+#0) = ##_start
170# CHECK: 3c40c000 memw(r0+#0) = ##131072 }
171
172# The rest:
173r1:0=combine(r2,##_start);
174# CHECK: 7302e000 r1:0 = combine(r2,##131072) }
175
176# R_HEX_32:
177r_hex_32:
178.word _start
179# CHECK: 00020000
180
181# R_HEX_16_X has 4 relocation mask variations
182# 0x48000000
183memw(##_start) = r0
184# CHECK: 4880c000 memw(##131072) = r0 }
185
186# 0x49000000
187r0 = memw(##_start)
188# CHECK: 4980c000 r0 = memw(##131072)
189
190# 0x78000000
191r0 = ##_start
192# CHECK: 7800c000 r0 = ##131072 }
193
194# 0xb0000000
195r0 = add(r1, ##_start)
196# CHECK: b001c000 r0 = add(r1,##131072) }
197
198# R_HEX_B9_PCREL:
199{r0=#1 ; jump #_start}
200# CHECK: jump 0x20000
201
202# R_HEX_B9_PCREL_X:
203{r0=#1 ; jump ##_start}
204# CHECK: jump 0x20000
205
206# R_HEX_B13_PCREL
207if (r0 == #0) jump:t #_start
208# CHECK: if (r0==#0) jump:t 0x20000
209
210# R_HEX_9_X
211p0 = !cmp.gtu(r0, ##_start)
212# CHECK: p0 = !cmp.gtu(r0,##131072)
213
214# R_HEX_10_X
215p0 = !cmp.gt(r0, ##_start)
216# CHECK: p0 = !cmp.gt(r0,##131072)
217
218# R_HEX_11_X
219r0 = memw(r1+##_start)
220# CHECK: r0 = memw(r1+##131072)
221
222memw(r0+##_start) = r1
223# CHECK: memw(r0+##131072) = r1
deps/lld/test/ELF/i386-linkonce.s created+9
...@@ -0,0 +1,9 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %p/Inputs/i386-linkonce.s -o %t2.o
4// RUN: llvm-ar rcs %t2.a %t2.o
5// RUN: ld.lld %t.o %t2.a -o %t
6
7 .globl _start
8_start:
9 call _strchr1
deps/lld/test/ELF/i386-pc8-pc16-addend.s+4-4
...@@ -4,11 +4,11 @@...@@ -4,11 +4,11 @@
4# RUN: ld.lld %t1.o -o %t.out4# RUN: ld.lld %t1.o -o %t.out
5# RUN: llvm-objdump -s -t %t.out | FileCheck %s5# RUN: llvm-objdump -s -t %t.out | FileCheck %s
6# CHECK: Contents of section .text:6# CHECK: Contents of section .text:
7# CHECK-NEXT: 11000 0200007# CHECK-NEXT: 401000 020000
8## 0x11003 - 0x11000 + addend(-1) = 0x028## 0x401003 - 0x401000 + addend(-1) = 0x02
9## 0x11003 - 0x11001 + addend(-2) = 0x00009## 0x401003 - 0x401001 + addend(-2) = 0x0000
10# CHECK: SYMBOL TABLE:10# CHECK: SYMBOL TABLE:
11# CHECK: 00011003 .und11# CHECK: 00401003 .und
1212
13.byte und-.-113.byte und-.-1
14.short und-.-214.short und-.-2
deps/lld/test/ELF/i386-retpoline-nopic.s+48-48
...@@ -8,56 +8,56 @@...@@ -8,56 +8,56 @@
88
9// CHECK: Disassembly of section .plt:9// CHECK: Disassembly of section .plt:
10// CHECK-NEXT: .plt:10// CHECK-NEXT: .plt:
11// CHECK-NEXT: 11010: ff 35 04 20 01 00 pushl 7373211// CHECK-NEXT: 401010: ff 35 04 20 40 00 pushl 4202500
12// CHECK-NEXT: 11016: 50 pushl %eax12// CHECK-NEXT: 401016: 50 pushl %eax
13// CHECK-NEXT: 11017: a1 08 20 01 00 movl 73736, %eax13// CHECK-NEXT: 401017: a1 08 20 40 00 movl 4202504, %eax
14// CHECK-NEXT: 1101c: e8 0f 00 00 00 calll 15 <.plt+0x20>14// CHECK-NEXT: 40101c: e8 0f 00 00 00 calll 15 <.plt+0x20>
15// CHECK-NEXT: 11021: f3 90 pause15// CHECK-NEXT: 401021: f3 90 pause
16// CHECK-NEXT: 11023: 0f ae e8 lfence16// CHECK-NEXT: 401023: 0f ae e8 lfence
17// CHECK-NEXT: 11026: eb f9 jmp -7 <.plt+0x11>17// CHECK-NEXT: 401026: eb f9 jmp -7 <.plt+0x11>
18// CHECK-NEXT: 11028: cc int318// CHECK-NEXT: 401028: cc int3
19// CHECK-NEXT: 11029: cc int319// CHECK-NEXT: 401029: cc int3
20// CHECK-NEXT: 1102a: cc int320// CHECK-NEXT: 40102a: cc int3
21// CHECK-NEXT: 1102b: cc int321// CHECK-NEXT: 40102b: cc int3
22// CHECK-NEXT: 1102c: cc int322// CHECK-NEXT: 40102c: cc int3
23// CHECK-NEXT: 1102d: cc int323// CHECK-NEXT: 40102d: cc int3
24// CHECK-NEXT: 1102e: cc int324// CHECK-NEXT: 40102e: cc int3
25// CHECK-NEXT: 1102f: cc int325// CHECK-NEXT: 40102f: cc int3
26// CHECK-NEXT: 11030: 89 0c 24 movl %ecx, (%esp)26// CHECK-NEXT: 401030: 89 0c 24 movl %ecx, (%esp)
27// CHECK-NEXT: 11033: 8b 4c 24 04 movl 4(%esp), %ecx27// CHECK-NEXT: 401033: 8b 4c 24 04 movl 4(%esp), %ecx
28// CHECK-NEXT: 11037: 89 44 24 04 movl %eax, 4(%esp)28// CHECK-NEXT: 401037: 89 44 24 04 movl %eax, 4(%esp)
29// CHECK-NEXT: 1103b: 89 c8 movl %ecx, %eax29// CHECK-NEXT: 40103b: 89 c8 movl %ecx, %eax
30// CHECK-NEXT: 1103d: 59 popl %ecx30// CHECK-NEXT: 40103d: 59 popl %ecx
31// CHECK-NEXT: 1103e: c3 retl31// CHECK-NEXT: 40103e: c3 retl
32// CHECK-NEXT: 1103f: cc int332// CHECK-NEXT: 40103f: cc int3
33// CHECK-NEXT: 11040: 50 pushl %eax33// CHECK-NEXT: 401040: 50 pushl %eax
34// CHECK-NEXT: 11041: a1 0c 20 01 00 movl 73740, %eax34// CHECK-NEXT: 401041: a1 0c 20 40 00 movl 4202508, %eax
35// CHECK-NEXT: 11046: e8 e5 ff ff ff calll -27 <.plt+0x20>35// CHECK-NEXT: 401046: e8 e5 ff ff ff calll -27 <.plt+0x20>
36// CHECK-NEXT: 1104b: e9 d1 ff ff ff jmp -47 <.plt+0x11>36// CHECK-NEXT: 40104b: e9 d1 ff ff ff jmp -47 <.plt+0x11>
37// CHECK-NEXT: 11050: 68 00 00 00 00 pushl $037// CHECK-NEXT: 401050: 68 00 00 00 00 pushl $0
38// CHECK-NEXT: 11055: e9 b6 ff ff ff jmp -74 <.plt>38// CHECK-NEXT: 401055: e9 b6 ff ff ff jmp -74 <.plt>
39// CHECK-NEXT: 1105a: cc int339// CHECK-NEXT: 40105a: cc int3
40// CHECK-NEXT: 1105b: cc int340// CHECK-NEXT: 40105b: cc int3
41// CHECK-NEXT: 1105c: cc int341// CHECK-NEXT: 40105c: cc int3
42// CHECK-NEXT: 1105d: cc int342// CHECK-NEXT: 40105d: cc int3
43// CHECK-NEXT: 1105e: cc int343// CHECK-NEXT: 40105e: cc int3
44// CHECK-NEXT: 1105f: cc int344// CHECK-NEXT: 40105f: cc int3
45// CHECK-NEXT: 11060: 50 pushl %eax45// CHECK-NEXT: 401060: 50 pushl %eax
46// CHECK-NEXT: 11061: a1 10 20 01 00 movl 73744, %eax46// CHECK-NEXT: 401061: a1 10 20 40 00 movl 4202512, %eax
47// CHECK-NEXT: 11066: e8 c5 ff ff ff calll -59 <.plt+0x20>47// CHECK-NEXT: 401066: e8 c5 ff ff ff calll -59 <.plt+0x20>
48// CHECK-NEXT: 1106b: e9 b1 ff ff ff jmp -79 <.plt+0x11>48// CHECK-NEXT: 40106b: e9 b1 ff ff ff jmp -79 <.plt+0x11>
49// CHECK-NEXT: 11070: 68 08 00 00 00 pushl $849// CHECK-NEXT: 401070: 68 08 00 00 00 pushl $8
50// CHECK-NEXT: 11075: e9 96 ff ff ff jmp -106 <.plt>50// CHECK-NEXT: 401075: e9 96 ff ff ff jmp -106 <.plt>
51// CHECK-NEXT: 1107a: cc int351// CHECK-NEXT: 40107a: cc int3
52// CHECK-NEXT: 1107b: cc int352// CHECK-NEXT: 40107b: cc int3
53// CHECK-NEXT: 1107c: cc int353// CHECK-NEXT: 40107c: cc int3
54// CHECK-NEXT: 1107d: cc int354// CHECK-NEXT: 40107d: cc int3
55// CHECK-NEXT: 1107e: cc int355// CHECK-NEXT: 40107e: cc int3
56// CHECK-NEXT: 1107f: cc int356// CHECK-NEXT: 40107f: cc int3
5757
58// CHECK: Contents of section .got.plt:58// CHECK: Contents of section .got.plt:
59// CHECK-NEXT: 00300100 00000000 00000000 5010010059// CHECK-NEXT: 00304000 00000000 00000000 50104000
60// CHECK-NEXT: 7010010060// CHECK-NEXT: 70104000
6161
62.global _start62.global _start
63_start:63_start:
deps/lld/test/ELF/image-base.s+3
...@@ -3,6 +3,9 @@...@@ -3,6 +3,9 @@
3# RUN: ld.lld -image-base=0x1000000 %t -o %t13# RUN: ld.lld -image-base=0x1000000 %t -o %t1
4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
55
6# RUN: not ld.lld -image-base=ABC %t -o %t1 2>&1 | FileCheck --check-prefix=ERR %s
7# ERR: error: -image-base: number expected, but got ABC
8
6# RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s9# RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s
7# WARN: warning: -image-base: address isn't multiple of page size: 0x100010# WARN: warning: -image-base: address isn't multiple of page size: 0x1000
811
deps/lld/test/ELF/incompatible-ar-first.s+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o
3// RUN: rm -f %t.a
3// RUN: llvm-ar rc %t.a %ta.o4// RUN: llvm-ar rc %t.a %ta.o
4// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o5// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
5// RUN: not ld.lld %t.a %tb.o -o /dev/null 2>&1 | FileCheck %s6// RUN: not ld.lld %t.a %tb.o -o /dev/null 2>&1 | FileCheck %s
deps/lld/test/ELF/incompatible.s+1
...@@ -48,6 +48,7 @@...@@ -48,6 +48,7 @@
48// We used to fail to identify this incompatibility and crash trying to48// We used to fail to identify this incompatibility and crash trying to
49// read a 64 bit file as a 32 bit one.49// read a 64 bit file as a 32 bit one.
50// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o50// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o
51// RUN: rm -f %t.a
51// RUN: llvm-ar rc %t.a %ta.o52// RUN: llvm-ar rc %t.a %ta.o
52// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o53// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
53// RUN: not ld.lld %t.a %tb.o 2>&1 -o %t | FileCheck --check-prefix=ARCHIVE %s54// RUN: not ld.lld %t.a %tb.o 2>&1 -o %t | FileCheck --check-prefix=ARCHIVE %s
deps/lld/test/ELF/invalid-linkerscript.test+7-1
...@@ -50,5 +50,11 @@...@@ -50,5 +50,11 @@
5050
51# RUN: echo "OUTPUT_FORMAT(x y z)" > %t851# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
52# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s52# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
53# ERR8: , expected, but got y53# RUN: not ld.lld -m elf_amd64 %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
54# ERR8: unknown output format name: x
54# ERR8: cannot open no-such-file:55# ERR8: cannot open no-such-file:
56
57# RUN: echo "OUTPUT_FORMAT(elf64-x86-64 y z)" > %t9
58# RUN: not ld.lld %t9 no-such-file 2>&1 | FileCheck -check-prefix=ERR9 %s
59# ERR9: , expected, but got y
60# ERR9: cannot open no-such-file:
deps/lld/test/ELF/invalid/Inputs/shentsize-zero.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/shentsize-zero.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/sht-group.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/sht-group.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so differ
deps/lld/test/ELF/invalid/comdat-broken.test created+25
...@@ -0,0 +1,25 @@
1# REQUIRES: x86
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
5# RUN: not ld.lld %t.o %t.o -o %t.exe 2>&1 | FileCheck %s
6
7# CHECK: error: {{.*}}.o: unsupported SHT_GROUP format
8
9--- !ELF
10FileHeader:
11 Class: ELFCLASS64
12 Data: ELFDATA2LSB
13 Type: ET_REL
14 Machine: EM_X86_64
15Sections:
16 - Name: .group
17 Type: SHT_GROUP
18 Link: .symtab
19 Info: foo
20 Members:
21 - SectionOrType: 0xFF
22 - SectionOrType: 3
23Symbols:
24 Global:
25 - Name: foo
deps/lld/test/ELF/invalid/ehframe-broken-relocation.test created+31
...@@ -0,0 +1,31 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld --icf=all %t.o -o /dev/null 2>&1 | FileCheck %s
3# CHECK: .eh_frame: relocation is not in any piece
4
5!ELF
6FileHeader:
7 Class: ELFCLASS64
8 Data: ELFDATA2LSB
9 OSABI: ELFOSABI_FREEBSD
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .eh_frame
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC]
16 Content: "1400000000000000017a5200017810011b0c070890010000140000001c00000000000000000000000000000000000000"
17 - Name: .rela.eh_frame
18 Type: SHT_RELA
19 Link: .symtab
20 Info: .eh_frame
21 Relocations:
22 - Offset: 0x99999999
23 Symbol: zed
24 Type: R_X86_64_64
25Symbols:
26 Global:
27 - Name: zed
28 Type: STT_FUNC
29 Section: .eh_frame
30 Value: 0x0
31 Size: 8
deps/lld/test/ELF/invalid/invalid-soname.test created+18
...@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.so
3# RUN: not ld.lld %t.so -o %t.exe 2>&1 | FileCheck %s
4
5# CHECK: error: {{.*}}.so: invalid DT_SONAME entry
6
7--- !ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 Type: ET_DYN
12 Machine: EM_X86_64
13Sections:
14 - Name: .test
15 Type: SHT_DYNAMIC
16 Flags: [ SHF_ALLOC ]
17 Content: "0e000000000000000000000000000001"
18 Link: .strtab
deps/lld/test/ELF/invalid/linkorder-invalid-sec.test created+16
...@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
4# CHECK: invalid sh_link index: 12345
5
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .linkorder
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_LINK_ORDER ]
16 Link: 12345
deps/lld/test/ELF/invalid/linkorder-invalid-sec2.test created+16
...@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
4# CHECK: invalid sh_link index: 0
5
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .linkorder
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_LINK_ORDER ]
16 Link: 0
deps/lld/test/ELF/invalid/merge-invalid-size.s-3
...@@ -3,8 +3,5 @@...@@ -3,8 +3,5 @@
3// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s3// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
4// CHECK: SHF_MERGE section size must be a multiple of sh_entsize4// CHECK: SHF_MERGE section size must be a multiple of sh_entsize
55
6// Test that we accept a zero sh_entsize.
7// RUN: ld.lld %p/Inputs/shentsize-zero.elf -o /dev/null
8
9.section .foo,"aM",@progbits,46.section .foo,"aM",@progbits,4
10.short 427.short 42
deps/lld/test/ELF/invalid/merge-zero-size.test created+21
...@@ -0,0 +1,21 @@
1# REQUIRES: x86
2
3# RUN: yaml2obj %s -o %t.o
4
5# Test that we accept a zero sh_entsize for SHF_MERGE section.
6# RUN: ld.lld %t.o -o %t.exe
7
8!ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 OSABI: ELFOSABI_FREEBSD
13 Type: ET_REL
14 Machine: EM_X86_64
15Sections:
16 - Type: SHT_PROGBITS
17 Name: .strings
18 Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
19 AddressAlign: 0x04
20 Content: "FFFFFFFFFFFFFFFF"
21 EntSize: 0x0
deps/lld/test/ELF/invalid/non-terminated-string.test created+19
...@@ -0,0 +1,19 @@
1# RUN: yaml2obj %s -o %t
2# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
3
4# CHECK: {{.*}}:(.merge): string is not null terminated
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 OSABI: ELFOSABI_FREEBSD
11 Type: ET_REL
12 Machine: EM_X86_64
13Sections:
14 - Type: SHT_PROGBITS
15 Name: .merge
16 Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
17 AddressAlign: 0x04
18 Content: "AABB"
19 EntSize: 0x2
deps/lld/test/ELF/invalid/sht-group-wrong-section.test created+22
...@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o %t.o -o %t.exe 2>&1 | FileCheck %s
4# CHECK: error: {{.*}}.o: invalid section index in group: 12345
5
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .group
14 Type: SHT_GROUP
15 Link: .symtab
16 Info: foo
17 Members:
18 - SectionOrType: GRP_COMDAT
19 - SectionOrType: 12345
20Symbols:
21 Global:
22 - Name: foo
deps/lld/test/ELF/invalid/sht-group.s deleted-3
...@@ -1,3 +0,0 @@
1## sht-group.elf contains SHT_GROUP section with invalid sh_info.
2# RUN: not ld.lld %p/Inputs/sht-group.elf -o /dev/null 2>&1 | FileCheck %s
3# CHECK: invalid symbol index
deps/lld/test/ELF/invalid/sht-group.test created+18
...@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
4# CHECK: invalid symbol index
5
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .group
14 Type: SHT_GROUP
15 Link: .symtab
16 Info: 12345
17 Members:
18 - SectionOrType: GRP_COMDAT
deps/lld/test/ELF/invalid/undefined-local-symbol-in-dso.test created+66
...@@ -0,0 +1,66 @@
1# REQUIRES: x86
2
3# LLD used to crash when linking against a DSO with an undefined STB_LOCAL
4# symbol in the global part of the dynamic symbol table (i.e. an STB_LOCAL
5# symbol with an index >= the sh_info of the dynamic symbol table section). Such
6# a DSO is very broken, because local symbols should precede all global symbols
7# in the symbol table, and because having a symbol that's both undefined and
8# STB_LOCAL is a nonsensical combination. Nevertheless, we should warn on such
9# input files instead of crashing.
10
11# We've found actual broken DSOs of this sort in the wild, but for this test, we
12# created a reduced broken input file. There are no tools capable of producing a
13# broken DSO of this nature, so instead we created a valid DSO with an undefined
14# global symbol in the dynamic symbol table and then manually edited the binary
15# to make that symbol local. The valid DSO was created as follows:
16
17```
18% cat undef.s
19.hidden bar
20bar:
21 movq foo@GOT, %rax
22
23% llvm-mc -triple=x86_64-linux-gnu -filetype=obj -o undef.o undef.s
24% ld.lld --no-rosegment -shared -o undefined-local-symbol-in-dso.so undef.o
25% strip undef.so
26```
27
28# (--no-rosegment and stripping are unnecessary; they just produce a smaller
29# binary)
30
31# This DSO should only have a single dynamic symbol table entry for foo, and
32# then we can use a small C program to modify that symbol table entry to be
33# STB_LOCAL instead of STB_GLOBAL.
34
35```
36#include <elf.h>
37#include <stdio.h>
38
39int main(int argc, char *argv[]) {
40 FILE *F = fopen(argv[1], "rb+");
41
42 Elf64_Ehdr Ehdr;
43 fread(&Ehdr, sizeof(Ehdr), 1, F);
44 fseek(F, Ehdr.e_shoff, SEEK_SET);
45
46 Elf64_Shdr Shdr;
47 do {
48 fread(&Shdr, sizeof(Shdr), 1, F);
49 } while (Shdr.sh_type != SHT_DYNSYM);
50
51 Elf64_Sym Sym;
52 fseek(F, Shdr.sh_offset + sizeof(Elf64_Sym), SEEK_SET);
53 fread(&Sym, sizeof(Sym), 1, F);
54 Sym.st_info = STB_LOCAL << 4 | ELF64_ST_TYPE(Sym.st_info);
55 fseek(F, Shdr.sh_offset + sizeof(Elf64_Sym), SEEK_SET);
56 fwrite(&Sym, sizeof(Sym), 1, F);
57 fclose(F);
58}
59```
60
61# (the C program just takes its input DSO and modifies the binding of the first
62# dynamic symbol table entry to be STB_LOCAL instead of STB_GLOBAL)
63
64# RUN: ld.lld %p/Inputs/undefined-local-symbol-in-dso.so -o %t 2>&1 | \
65# RUN: FileCheck -check-prefix=WARN %s
66# WARN: found local symbol 'foo' in global part of symbol table in file {{.*}}undefined-local-symbol-in-dso.so
deps/lld/test/ELF/lazy-arch-conflict.s created+7
...@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3# RUN: echo '.globl foo; .weak foo; .quad foo;' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t64.o
4# RUN: echo '.globl foo; foo:' | llvm-mc -filetype=obj -triple=i686-pc-linux - -o %t32.o
5# RUN: not ld.lld %t64.o --start-lib %t32.o --end-lib -o /dev/null 2>&1 | FileCheck %s
6
7# CHECK: error: incompatible file: {{.*}}32.o
deps/lld/test/ELF/linkerscript/align-r.test+1-1
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
44
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o
6# RUN: ld.lld -r -o %t2.o --script %s %t1.o6# RUN: ld.lld -r -o %t2.o --script %s %t1.o
7# RUN: llvm-readelf -s %t2.o | FileCheck %s7# RUN: llvm-readelf -S %t2.o | FileCheck %s
88
9# CHECK: Section Headers:9# CHECK: Section Headers:
10# CHECK-NEXT: Name Type Address Off Size ES Flg Lk Inf Al10# CHECK-NEXT: Name Type Address Off Size ES Flg Lk Inf Al
deps/lld/test/ELF/linkerscript/align4.test-1
...@@ -4,7 +4,6 @@...@@ -4,7 +4,6 @@
4# RUN: llvm-objdump -t %t | FileCheck %s4# RUN: llvm-objdump -t %t | FileCheck %s
55
6# CHECK-LABEL: SYMBOL TABLE:6# CHECK-LABEL: SYMBOL TABLE:
7# CHECK-NEXT: 0000000000000000 *UND* 00000000
8# CHECK-NEXT: 0000000000014008 .text 00000000 _start7# CHECK-NEXT: 0000000000014008 .text 00000000 _start
9# CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__8# CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
10# CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR9# CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR
deps/lld/test/ELF/linkerscript/discard-section-err.s+6-14
...@@ -7,25 +7,17 @@...@@ -7,25 +7,17 @@
7# RUN: FileCheck -check-prefix=SHSTRTAB %s7# RUN: FileCheck -check-prefix=SHSTRTAB %s
8# SHSTRTAB: discarding .shstrtab section is not allowed8# SHSTRTAB: discarding .shstrtab section is not allowed
99
10## We allow discarding .dynamic, check we don't crash.
10# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script11# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script
11# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \12# RUN: ld.lld -pie -o %t --script %t.script %t.o
12# RUN: FileCheck -check-prefix=DYNAMIC %s
13# DYNAMIC: discarding .dynamic section is not allowed
1413
14## We allow discarding .dynsym, check we don't crash.
15# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script15# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script
16# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \16# RUN: ld.lld -pie -o %t --script %t.script %t.o
17# RUN: FileCheck -check-prefix=DYNSYM %s
18# DYNSYM: discarding .dynsym section is not allowed
1917
18## We allow discarding .dynstr, check we don't crash.
20# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script19# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script
21# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \20# RUN: ld.lld -pie -o %t --script %t.script %t.o
22# RUN: FileCheck -check-prefix=DYNSTR %s
23# DYNSTR: discarding .dynstr section is not allowed
24
25# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.plt) } }" > %t.script
26# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
27# RUN: FileCheck -check-prefix=RELAPLT %s
28# RELAPLT: discarding .rela.plt section is not allowed
2921
30# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.dyn) } }" > %t.script22# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.dyn) } }" > %t.script
31# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \23# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
deps/lld/test/ELF/linkerscript/filename-spec.s+1
...@@ -43,6 +43,7 @@...@@ -43,6 +43,7 @@
43# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o43# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
45# RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o45# RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o
46# RUN: rm -f %t.testdir1/lib1.a %t.testdir2/lib2.a
46# RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o47# RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o
47# RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o48# RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o
4849
deps/lld/test/ELF/linkerscript/icf.s created+11
...@@ -0,0 +1,11 @@
1# REQUIRES: x86
2
3# RUN: echo "foo = 1; bar = 2;" > %t.script
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld %t.o %t.script -o %t --icf=all --print-icf-sections | count 0
6
7.section .text.foo,"ax",@progbits
8jmp foo
9
10.section .text.bar,"ax",@progbits
11jmp bar
deps/lld/test/ELF/linkerscript/info-section-type.s+9
...@@ -29,5 +29,14 @@...@@ -29,5 +29,14 @@
29# RUN: ld.lld -o %t --script %t.script %t.o29# RUN: ld.lld -o %t --script %t.script %t.o
30# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC30# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
3131
32# RUN: echo "SECTIONS { .bar 0x20000 (INFO) : { *(.foo) } };" > %t.script
33# RUN: ld.lld -o %t --script %t.script %t.o
34# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
35
36# RUN: echo "SECTIONS { .bar 0x20000 (BAR) : { *(.foo) } };" > %t.script
37# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 |\
38# RUN: FileCheck %s --check-prefix=UNKNOWN
39# UNKNOWN: unknown section directive: BAR
40
32.section .foo,"a",@progbits41.section .foo,"a",@progbits
33.zero 142.zero 1
deps/lld/test/ELF/linkerscript/lazy-symbols.test+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t12# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
3# RUN: rm -f %tar
3# RUN: llvm-ar rcs %tar %t14# RUN: llvm-ar rcs %tar %t1
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t25# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t2
5# RUN: ld.lld %t2 %tar --script %s -o %tout6# RUN: ld.lld %t2 %tar --script %s -o %tout
deps/lld/test/ELF/linkerscript/map-file.test+4-4
...@@ -44,10 +44,10 @@ SECTIONS {...@@ -44,10 +44,10 @@ SECTIONS {
44# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 )44# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 )
45# CHECK-NEXT: 225d 225d 0 1 foo = .45# CHECK-NEXT: 225d 225d 0 1 foo = .
46# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x2646# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26
47# CHECK-NEXT: 225d 0 0 1 sym1 = .47# CHECK-NEXT: 225d 225d 0 1 sym1 = .
48# CHECK-NEXT: 225d 0 500 1 . += 0x50048# CHECK-NEXT: 225d 225d 500 1 . += 0x500
49# CHECK-NEXT: 275d 0 0 1 sym2 = .49# CHECK-NEXT: 275d 275d 0 1 sym2 = .
50# CHECK-NEXT: 275d 0 0 1 PROVIDE ( sym3 = 42 )50# CHECK-NEXT: 275d 275d 0 1 PROVIDE ( sym3 = 42 )
51# CHECK-NEXT: 2760 2760 10 4 .text51# CHECK-NEXT: 2760 2760 10 4 .text
52# CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)52# CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
53# CHECK-NEXT: 0 0 8 1 .comment53# CHECK-NEXT: 0 0 8 1 .comment
deps/lld/test/ELF/linkerscript/map-file2.test+12-10
...@@ -8,6 +8,7 @@ SECTIONS {...@@ -8,6 +8,7 @@ SECTIONS {
8 .aaa : { *(.aaa.*) }8 .aaa : { *(.aaa.*) }
9 .bbb : AT(0x2000) { *(.bbb.*) }9 .bbb : AT(0x2000) { *(.bbb.*) }
10 .ccc : AT(0x3000) { *(.ccc.*) }10 .ccc : AT(0x3000) { *(.ccc.*) }
11 . += 0x100;
11 .ddd : {12 .ddd : {
12 BYTE(0x11)13 BYTE(0x11)
13 . += 0x100;14 . += 0x100;
...@@ -24,16 +25,17 @@ SECTIONS {...@@ -24,16 +25,17 @@ SECTIONS {
24# CHECK-NEXT: 1008 2000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb)25# CHECK-NEXT: 1008 2000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb)
25# CHECK-NEXT: 1010 3000 8 1 .ccc26# CHECK-NEXT: 1010 3000 8 1 .ccc
26# CHECK-NEXT: 1010 3000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc)27# CHECK-NEXT: 1010 3000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc)
27# CHECK-NEXT: 1018 3008 109 1 .ddd28# CHECK-NEXT: 1018 3008 100 1 . += 0x100
28# CHECK-NEXT: 1018 3008 1 1 BYTE ( 0x11 )29# CHECK-NEXT: 1118 3108 109 1 .ddd
29# CHECK-NEXT: 1019 3009 100 1 . += 0x10030# CHECK-NEXT: 1118 3108 1 1 BYTE ( 0x11 )
30# CHECK-NEXT: 1119 3109 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd)31# CHECK-NEXT: 1119 3109 100 1 . += 0x100
31# CHECK-NEXT: 1128 3118 34 8 .eh_frame32# CHECK-NEXT: 1219 3209 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd)
32# CHECK-NEXT: 1128 3118 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0)33# CHECK-NEXT: 1228 3218 34 8 .eh_frame
33# CHECK-NEXT: 115c 314c 1 4 .text34# CHECK-NEXT: 1228 3218 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0)
34# CHECK-NEXT: 115c 314c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text)35# CHECK-NEXT: 125c 324c 1 4 .text
35# CHECK-NEXT: 115c 314c 0 1 f(int)36# CHECK-NEXT: 125c 324c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text)
36# CHECK-NEXT: 115c 314c 0 1 _start37# CHECK-NEXT: 125c 324c 0 1 f(int)
38# CHECK-NEXT: 125c 324c 0 1 _start
37# CHECK-NEXT: 0 0 8 1 .comment39# CHECK-NEXT: 0 0 8 1 .comment
38# CHECK-NEXT: 0 0 8 1 <internal>:(.comment)40# CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
39# CHECK-NEXT: 0 0 48 8 .symtab41# CHECK-NEXT: 0 0 48 8 .symtab
deps/lld/test/ELF/linkerscript/memory-include.test created+23
...@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: echo '.section .text,"ax"; .global _start; nop' > %t.s
4# RUN: echo '.section .data,"aw"; .quad 0' >> %t.s
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
6
7# RUN: echo "RAM2 (rwx): ORIGIN = 0x3000, LENGTH = 0x100" > %t.inc
8# RUN: ld.lld -o %t.elf --script %s %t.o -L %T
9# RUN: llvm-objdump -section-headers %t.elf | FileCheck %s
10# CHECK: .data 00000008 0000000000002000 DATA
11# CHECK: .data2 00000008 0000000000003000 DATA
12
13MEMORY {
14 ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100
15 RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100
16 INCLUDE "memory-include.test.tmp.inc"
17}
18
19SECTIONS {
20 .text : { *(.text*) } > ROM
21 .data : { *(.data*) } > RAM
22 .data2 : { QUAD(0) } > RAM2
23}
deps/lld/test/ELF/linkerscript/merge-nonalloc.s created+14
...@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .text : { *(.text) *(.nonalloc) } }" > %t.script
4# RUN: ld.lld -shared -o %t.exe %t.script %t.o
5# RUN: llvm-objdump -syms %t.exe | FileCheck %s
6
7# CHECK: .text 00000000 nonalloc_start
8
9_start:
10 nop
11
12.section .nonalloc,"",@progbits
13nonalloc_start:
14 .long 0xcafe
deps/lld/test/ELF/linkerscript/no-filename-spec.s created+17
...@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: echo '.section .bar, "a"; .quad 1;' | \
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %tfile1.o
4# RUN: echo '.section .zed, "a"; .quad 2;' | \
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %tfile2.o
6
7## We have a file name and no input sections description. In that case, all
8## sections from the file specified should be included. Check that.
9# RUN: ld.lld -o %t --script %s %tfile1.o %tfile2.o
10# RUN: llvm-objdump -s %t | FileCheck %s
11
12# CHECK: Contents of section .foo:
13# CHECK-NEXT: 01000000 00000000 02000000 00000000
14
15SECTIONS {
16 .foo : { *file1.o *file2.o }
17}
deps/lld/test/ELF/linkerscript/non-alloc-segment.s+1-1
...@@ -16,7 +16,7 @@...@@ -16,7 +16,7 @@
16# RUN: .foo : {*(.foo)} :foo \16# RUN: .foo : {*(.foo)} :foo \
17# RUN: }" > %t.script17# RUN: }" > %t.script
18# RUN: ld.lld -o %t --script %t.script %t.o18# RUN: ld.lld -o %t --script %t.script %t.o
19# RUN: llvm-readelf -s -l %t | FileCheck %s19# RUN: llvm-readelf -S -l %t | FileCheck %s
20# RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s20# RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s
2121
22# CHECK: Program Headers:22# CHECK: Program Headers:
deps/lld/test/ELF/linkerscript/non-alloc.s+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
33
4# RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script4# RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script
5# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared5# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
6# RUN: llvm-readelf -s -l %t | FileCheck %s6# RUN: llvm-readelf -S -l %t | FileCheck %s
77
8# Test that we create all necessary PT_LOAD. We use to stop at the first8# Test that we create all necessary PT_LOAD. We use to stop at the first
9# non-alloc, causing us to not create PT_LOAD for linker generated sections.9# non-alloc, causing us to not create PT_LOAD for linker generated sections.
deps/lld/test/ELF/linkerscript/orphan-discard.s+1-1
...@@ -10,7 +10,7 @@...@@ -10,7 +10,7 @@
10# RUN: /DISCARD/ : { *(.comment) } \10# RUN: /DISCARD/ : { *(.comment) } \
11# RUN: }" > %t.script11# RUN: }" > %t.script
12# RUN: ld.lld -o %t --script %t.script %t.o12# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -s -symbols %t | FileCheck %s13# RUN: llvm-readelf -S -symbols %t | FileCheck %s
1414
15# CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 409615# CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 4096
16# CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end16# CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end
deps/lld/test/ELF/linkerscript/orphan-phdrs.s+1-1
...@@ -10,7 +10,7 @@...@@ -10,7 +10,7 @@
10# RUN: .rw : { *(.rw) } \10# RUN: .rw : { *(.rw) } \
11# RUN: }" > %t.script11# RUN: }" > %t.script
12# RUN: ld.lld -o %t --script %t.script %t.o12# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -s -l %t | FileCheck %s13# RUN: llvm-readelf -S -l %t | FileCheck %s
1414
15## Check that the orphan section is placed correctly and belongs to15## Check that the orphan section is placed correctly and belongs to
16## the correct segment.16## the correct segment.
deps/lld/test/ELF/linkerscript/ouputformat.s deleted-9
...@@ -1,9 +0,0 @@
1# REQUIRES: x86
2# RUN: echo "OUTPUT_FORMAT(x, y, z)" > %t.script
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
4# RUN: ld.lld -shared -o %t2 %t1 %t.script
5# RUN: llvm-readobj %t2 > /dev/null
6
7# RUN: echo "OUTPUT_FORMAT(x, y)" > %t.script
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
9# RUN: not ld.lld -shared -o %t2 %t1 %t.script
deps/lld/test/ELF/linkerscript/output-section-include.test created+30
...@@ -0,0 +1,30 @@
1# REQUIRES: x86
2
3# RUN: echo '.section .text,"ax"; .global _start; nop' > %t.s
4# RUN: echo '.section .data,"aw"; .quad 0' >> %t.s
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
6
7## Empty include file.
8# RUN: echo "" > %t.inc
9# RUN: ld.lld -o %t.elf --script %s %t.o -L %T
10# RUN: llvm-objdump -section-headers %t.elf | FileCheck %s --check-prefix=CHECK1
11# CHECK1: .data 00000008 0000000000002000 DATA
12
13## Non-empty include file.
14# RUN: echo "QUAD(0)" > %t.inc
15# RUN: ld.lld -o %t.elf --script %s %t.o -L %T
16# RUN: llvm-objdump -section-headers %t.elf | FileCheck %s --check-prefix=CHECK2
17# CHECK2: .data 00000010 0000000000002000 DATA
18
19MEMORY {
20 ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100
21 RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100
22}
23
24SECTIONS {
25 .text : { *(.text*) } > ROM
26 .data : {
27 *(.data*)
28 INCLUDE "output-section-include.test.tmp.inc"
29 } > RAM
30}
deps/lld/test/ELF/linkerscript/output-too-large.s+6
...@@ -1,7 +1,13 @@...@@ -1,7 +1,13 @@
1# REQUIRES: x861# REQUIRES: x86
2
2# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o3# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script4# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
4# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s5# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
8# RUN: echo "SECTIONS { .text : { . = 0x8fffffffffffffff; *(.text*); } }" > %t.script
9# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s
10
5# CHECK: error: output file too large11# CHECK: error: output file too large
612
7.global _start13.global _start
deps/lld/test/ELF/linkerscript/phdrs.s+8
...@@ -130,6 +130,14 @@...@@ -130,6 +130,14 @@
130130
131# BADHDR: {{.*}}.script:1: section header 'bar' is not listed in PHDRS131# BADHDR: {{.*}}.script:1: section header 'bar' is not listed in PHDRS
132132
133# RUN: echo "PHDRS { text PT_LOAD FOOHDR; }" > %t1.script
134# RUN: not ld.lld -o /dev/null --script %t1.script %t 2>&1 | FileCheck --check-prefix=FOOHDR %s
135# FOOHDR: error: {{.*}}.script:1: unexpected header attribute: FOOHDR
136
137# RUN: echo "PHDRS { text PT_FOO FOOHDR; }" > %t1.script
138# RUN: not ld.lld -o /dev/null --script %t1.script %t 2>&1 | FileCheck --check-prefix=PTFOO %s
139# PTFOO: invalid program header type: PT_FOO
140
133.global _start141.global _start
134_start:142_start:
135 nop143 nop
deps/lld/test/ELF/linkerscript/provide-shared2.s+1-1
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
6# RUN: ld.lld -o %t --script %t.script %t.o %t2.so6# RUN: ld.lld -o %t --script %t.script %t.o %t2.so
7# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s7# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s
88
9# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@9# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo
1010
11.global _start11.global _start
12_start:12_start:
deps/lld/test/ELF/linkerscript/relocatable-discard.s created+21
...@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.discard.*) }}" > %t.script
4# RUN: ld.lld -o %t --script %t.script -r %t.o
5# RUN: llvm-readobj -sections %t | FileCheck %s
6
7## Test shows that we do not crash after discarding the .discard.foo with -r.
8## Previously it happened because of 2 reasons:
9## 1) .rela.discard.foo was not handled properly and was not discarded.
10## Remaining reference was invalid and caused the crash.
11## 2) Third-party section .debug_info referencing discarded section
12## did not handle this case properly and tried to apply the
13## relocation instead of ignoring it.
14
15# CHECK-NOT: .discard
16
17.section .discard.foo,"ax"
18callq fn@PLT
19
20.section .debug_info,"",@progbits
21.long .discard.foo
deps/lld/test/ELF/linkerscript/section-include.test created+32
...@@ -0,0 +1,32 @@
1# REQUIRES: x86
2
3# RUN: echo '.section .text,"ax"; .global _start; nop' > %t.s
4# RUN: echo '.section .data,"aw"; .quad 0' >> %t.s
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
6
7## Empty include file.
8# RUN: echo "" > %t.inc
9# RUN: ld.lld -o %t.elf --script %s %t.o -L %T
10# RUN: llvm-objdump -section-headers %t.elf | FileCheck %s --check-prefix=CHECK1
11# CHECK1: .data 00000008 0000000000002000 DATA
12# CHECK1-NEXT: .data3 00000008 0000000000002008 DATA
13
14## Non-empty include file.
15# RUN: echo ".data2 : { QUAD(0) } > RAM" > %t.inc
16# RUN: ld.lld -o %t.elf --script %s %t.o -L %T
17# RUN: llvm-objdump -section-headers %t.elf | FileCheck %s --check-prefix=CHECK2
18# CHECK2: .data 00000008 0000000000002000 DATA
19# CHECK2-NEXT: .data2 00000008 0000000000002008 DATA
20# CHECK2-NEXT: .data3 00000008 0000000000002010 DATA
21
22MEMORY {
23 ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100
24 RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100
25}
26
27SECTIONS {
28 .text : { *(.text*) } > ROM
29 .data : { *(.data*) } > RAM
30 INCLUDE "section-include.test.tmp.inc"
31 .data3 : { QUAD(0) } > RAM
32}
deps/lld/test/ELF/linkerscript/sections-va-overflow.test+2-2
...@@ -7,7 +7,7 @@ PHDRS {...@@ -7,7 +7,7 @@ PHDRS {
7 ph_text PT_LOAD FILEHDR PHDRS FLAGS (0x1 | 0x4);7 ph_text PT_LOAD FILEHDR PHDRS FLAGS (0x1 | 0x4);
8}8}
99
10SECTIONS { 10SECTIONS {
11 . = 0xffffffff20000000;11 . = 0xffffffff20000000;
12 .text : { *(.text*) } : ph_text12 .text : { *(.text*) } : ph_text
13 .test 0x1000 : { BYTE(0) }13 .test 0x1000 : { BYTE(0) }
...@@ -18,5 +18,5 @@ SECTIONS {...@@ -18,5 +18,5 @@ SECTIONS {
18## with VA 0xffffffff20000000. That might be technically correct, but most probably18## with VA 0xffffffff20000000. That might be technically correct, but most probably
19## is a result of a broken script file and causes file offset calculation overflow.19## is a result of a broken script file and causes file offset calculation overflow.
20## It seems we do not have to support it, so we don't and we report an error in this case.20## It seems we do not have to support it, so we don't and we report an error in this case.
21# ERR: error: unable to place section .text at file offset [0xFFFFFFFF20000000, 0xFFFFFFFE40000000]; check your linker script for overflows21# ERR: error: unable to place section .text at file offset [0xFFFFFFFF20000000, 0xFFFFFFFF20000000]; check your linker script for overflows
22# ERR-NOT: unable to place section .bss22# ERR-NOT: unable to place section .bss
deps/lld/test/ELF/linkerscript/segment-none.s+2-2
...@@ -9,7 +9,7 @@...@@ -9,7 +9,7 @@
9# RUN: .foo : {*(.foo)} :NONE \9# RUN: .foo : {*(.foo)} :NONE \
10# RUN: }" > %t.script10# RUN: }" > %t.script
11# RUN: ld.lld -o %t --script %t.script %t.o11# RUN: ld.lld -o %t --script %t.script %t.o
12# RUN: llvm-readelf -s -l %t | FileCheck %s12# RUN: llvm-readelf -S -l %t | FileCheck %s
1313
14## Test that section .foo is placed in segment NONE when assigned to segment14## Test that section .foo is placed in segment NONE when assigned to segment
15## NONE in the linker script and segment NONE is defined.15## NONE in the linker script and segment NONE is defined.
...@@ -19,7 +19,7 @@...@@ -19,7 +19,7 @@
19# RUN: .foo : {*(.foo)} :NONE \19# RUN: .foo : {*(.foo)} :NONE \
20# RUN: }" > %t.script20# RUN: }" > %t.script
21# RUN: ld.lld -o %t --script %t.script %t.o21# RUN: ld.lld -o %t --script %t.script %t.o
22# RUN: llvm-readelf -s -l %t | FileCheck --check-prefix=DEFINED %s22# RUN: llvm-readelf -S -l %t | FileCheck --check-prefix=DEFINED %s
2323
24# CHECK: Section to Segment mapping:24# CHECK: Section to Segment mapping:
25# CHECK-NEXT: Segment Sections...25# CHECK-NEXT: Segment Sections...
deps/lld/test/ELF/linkerscript/sizeof.s-1
...@@ -18,7 +18,6 @@...@@ -18,7 +18,6 @@
18# CHECK-NEXT: 2 .bbb 0000001018# CHECK-NEXT: 2 .bbb 00000010
19# CHECK-NEXT: 3 .ccc 0000001819# CHECK-NEXT: 3 .ccc 00000018
20# CHECK: SYMBOL TABLE:20# CHECK: SYMBOL TABLE:
21# CHECK-NEXT: 0000000000000000 *UND* 00000000
22# CHECK-NEXT: .text 00000000 _start21# CHECK-NEXT: .text 00000000 _start
23# CHECK-NEXT: 0000000000000008 *ABS* 00000000 _aaa22# CHECK-NEXT: 0000000000000008 *ABS* 00000000 _aaa
24# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb23# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
deps/lld/test/ELF/linkerscript/sizeofheaders.s-1
...@@ -9,7 +9,6 @@...@@ -9,7 +9,6 @@
9# RUN: llvm-objdump -t %t1 | FileCheck %s9# RUN: llvm-objdump -t %t1 | FileCheck %s
1010
11#CHECK: SYMBOL TABLE:11#CHECK: SYMBOL TABLE:
12#CHECK-NEXT: 0000000000000000 *UND* 00000000
13#CHECK-NEXT: 00000000000000e8 .text 00000000 _start12#CHECK-NEXT: 00000000000000e8 .text 00000000 _start
14#CHECK-NEXT: 00000000000000e8 *ABS* 00000000 _size13#CHECK-NEXT: 00000000000000e8 *ABS* 00000000 _size
1514
deps/lld/test/ELF/linkerscript/sort-init.s+4-2
...@@ -1,16 +1,18 @@...@@ -1,16 +1,18 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: echo "SECTIONS { .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array.*)) } }" > %t1.script3# RUN: echo "SECTIONS { .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array.* foo*)) } }" > %t1.script
4# RUN: ld.lld --script %t1.script %t1.o -o %t24# RUN: ld.lld --script %t1.script %t1.o -o %t2
5# RUN: llvm-objdump -s %t2 | FileCheck %s5# RUN: llvm-objdump -s %t2 | FileCheck %s
66
7# CHECK: Contents of section .init_array:7# CHECK: Contents of section .init_array:
8# CHECK-NEXT: 03020000 00000000 0104058# CHECK-NEXT: 03020000 00060000 010405
99
10.globl _start10.globl _start
11_start:11_start:
12 nop12 nop
1313
14.section foo, "aw", @init_array
15 .byte 6
14.section .init_array, "aw", @init_array16.section .init_array, "aw", @init_array
15 .align 817 .align 8
16 .byte 118 .byte 1
deps/lld/test/ELF/linkerscript/sort-non-script.s+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
33
4# RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script4# RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script
5# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared5# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
6# RUN: llvm-readelf -s %t | FileCheck %s6# RUN: llvm-readelf -S %t | FileCheck %s
77
8# CHECK: .dynsym {{.*}} A8# CHECK: .dynsym {{.*}} A
9# CHECK-NEXT: .hash {{.*}} A9# CHECK-NEXT: .hash {{.*}} A
deps/lld/test/ELF/linkerscript/symbol-assignexpr.s-1
...@@ -25,7 +25,6 @@...@@ -25,7 +25,6 @@
25# RUN: llvm-objdump -t %t1 | FileCheck %s25# RUN: llvm-objdump -t %t1 | FileCheck %s
2626
27# CHECK: SYMBOL TABLE:27# CHECK: SYMBOL TABLE:
28# CHECK-NEXT: 0000000000000000 *UND* 00000000
29# CHECK-NEXT: 0000000000000000 .text 00000000 _start28# CHECK-NEXT: 0000000000000000 .text 00000000 _start
30# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar29# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
31# CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz30# CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz
deps/lld/test/ELF/linkerscript/symbol-location.s created+15
...@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "foo = 1;" > %t.script
4# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | FileCheck %s
5
6## Here we check that symbol 'foo' location is reported properly.
7
8# CHECK: error: relocation R_X86_64_PLT32 cannot refer to absolute symbol: foo
9# CHECK: >>> defined in {{.*}}.script:1
10# CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
11
12.text
13.globl _start
14_start:
15 call foo@PLT
deps/lld/test/ELF/linkerscript/symbol-memoryexpr.s-1
...@@ -13,7 +13,6 @@...@@ -13,7 +13,6 @@
13# RUN: llvm-objdump -t %t1 | FileCheck %s13# RUN: llvm-objdump -t %t1 | FileCheck %s
1414
15# CHECK: SYMBOL TABLE:15# CHECK: SYMBOL TABLE:
16# CHECK-NEXT: 0000000000000000 *UND* 00000000
17# CHECK-NEXT: 0000000000008000 .text 00000000 _start16# CHECK-NEXT: 0000000000008000 .text 00000000 _start
18# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin17# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
19# CHECK-NEXT: 0000000000040000 *ABS* 00000000 length18# CHECK-NEXT: 0000000000040000 *ABS* 00000000 length
deps/lld/test/ELF/linkerscript/target.s created+18
...@@ -0,0 +1,18 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: echo "TARGET(binary) INPUT(\"%t.o\") TARGET(elf64-x86-64) INPUT(\"%t.o\")" > %t.script
5# RUN: ld.lld --script %t.script -o %t.exe
6# RUN: llvm-readelf -symbols %t.exe | FileCheck %s
7
8# CHECK: _binary_
9# CHECK: foobar
10
11# RUN: echo "TARGET(foo)" > %t2.script
12# RUN: not ld.lld --script %t2.script -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s
13
14# ERR: unknown target: foo
15
16.global foobar
17foobar:
18 nop
deps/lld/test/ELF/linkerscript/unused-synthetic.s+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7# RUN: }" > %t.script7# RUN: }" > %t.script
8# RUN: ld.lld -shared -o %t.so --script %t.script %t.o8# RUN: ld.lld -shared -o %t.so --script %t.script %t.o
99
10# RUN: llvm-readelf -s %t.so | FileCheck %s10# RUN: llvm-readelf -S %t.so | FileCheck %s
11# CHECK-NOT: .got11# CHECK-NOT: .got
12# CHECK-NOT: .plt12# CHECK-NOT: .plt
13# CHECK: .dynsym13# CHECK: .dynsym
deps/lld/test/ELF/linkerscript/version-script.s+3-3
...@@ -14,11 +14,11 @@...@@ -14,11 +14,11 @@
14# CHECK: Symbols [14# CHECK: Symbols [
15# CHECK-NEXT: Symbol {15# CHECK-NEXT: Symbol {
16# CHECK-NEXT: Version: 016# CHECK-NEXT: Version: 0
17# CHECK-NEXT: Name: @17# CHECK-NEXT: Name:
18# CHECK-NEXT: }18# CHECK-NEXT: }
19# CHECK-NEXT: Symbol {19# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Version: 020# CHECK-NEXT: Version: 0
21# CHECK-NEXT: Name: und@21# CHECK-NEXT: Name: und
22# CHECK-NEXT: }22# CHECK-NEXT: }
23# CHECK-NEXT: Symbol {23# CHECK-NEXT: Symbol {
24# CHECK-NEXT: Version: 224# CHECK-NEXT: Version: 2
...@@ -41,7 +41,7 @@...@@ -41,7 +41,7 @@
41# UNDEF: Symbols [41# UNDEF: Symbols [
42# UNDEF-NEXT: Symbol {42# UNDEF-NEXT: Symbol {
43# UNDEF-NEXT: Version: 043# UNDEF-NEXT: Version: 0
44# UNDEF-NEXT: Name: @44# UNDEF-NEXT: Name:
45# UNDEF-NEXT: }45# UNDEF-NEXT: }
46# UNDEF-NEXT: Symbol {46# UNDEF-NEXT: Symbol {
47# UNDEF-NEXT: Version: 247# UNDEF-NEXT: Version: 2
deps/lld/test/ELF/local-dynamic.s+2-2
...@@ -65,7 +65,7 @@...@@ -65,7 +65,7 @@
6565
66// CHECK: DynamicSymbols [66// CHECK: DynamicSymbols [
67// CHECK-NEXT: Symbol {67// CHECK-NEXT: Symbol {
68// CHECK-NEXT: Name: @68// CHECK-NEXT: Name:
69// CHECK-NEXT: Value: 0x069// CHECK-NEXT: Value: 0x0
70// CHECK-NEXT: Size: 070// CHECK-NEXT: Size: 0
71// CHECK-NEXT: Binding: Local71// CHECK-NEXT: Binding: Local
...@@ -74,7 +74,7 @@...@@ -74,7 +74,7 @@
74// CHECK-NEXT: Section: Undefined74// CHECK-NEXT: Section: Undefined
75// CHECK-NEXT: }75// CHECK-NEXT: }
76// CHECK-NEXT: Symbol {76// CHECK-NEXT: Symbol {
77// CHECK-NEXT: Name: _start@77// CHECK-NEXT: Name: _start
78// CHECK-NEXT: Value:78// CHECK-NEXT: Value:
79// CHECK-NEXT: Size: 079// CHECK-NEXT: Size: 0
80// CHECK-NEXT: Binding: Global80// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/local-ver-preemptible.s created+22
...@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: echo '.global foo; .type foo, @function; foo:' | \
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.so.o
4# RUN: ld.lld %t.so.o -o %t.so -shared
5
6# RUN: echo "{ global: main; local: *; };" > %t.script
7
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
9# RUN: ld.lld %t.o %t.so -o %t -version-script %t.script
10# RUN: llvm-readelf -r --symbols %t | FileCheck %s
11
12# CHECK: Relocation section '.rela.plt' at offset {{.*}} contains 1 entries:
13# CHECK: R_X86_64_JUMP_SLOT 0000000000201020 foo + 0
14
15# CHECK: Symbol table '.dynsym' contains 2 entries:
16# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
17# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
18# CHECK-NEXT: 1: 0000000000201020 0 FUNC GLOBAL DEFAULT UND foo
19
20.globl _start
21_start:
22 movl $foo - ., %eax
deps/lld/test/ELF/lto-plugin-ignore.s+2-2
...@@ -6,5 +6,5 @@...@@ -6,5 +6,5 @@
6# RUN: -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null6# RUN: -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null
77
8# RUN: not ld.lld %t -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s8# RUN: not ld.lld %t -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s
9# CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'9# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'
10# CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'10# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'
deps/lld/test/ELF/lto/Inputs/libcall-archive.s created+2
...@@ -0,0 +1,2 @@
1.globl __sync_val_compare_and_swap_8
2__sync_val_compare_and_swap_8:
deps/lld/test/ELF/lto/amdgcn.ll created+12
...@@ -0,0 +1,12 @@
1; REQUIRES: amdgpu
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld %t.o -o %t
4
5; Make sure the amdgcn triple is handled
6
7target triple = "amdgcn-amd-amdhsa"
8target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
9
10define void @_start() {
11 ret void
12}
deps/lld/test/ELF/lto/cache.ll+20
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1; REQUIRES: x861; REQUIRES: x86
2; NetBSD: noatime mounts currently inhibit 'touch' from updating atime
3; UNSUPPORTED: system-netbsd
24
3; RUN: opt -module-hash -module-summary %s -o %t.o5; RUN: opt -module-hash -module-summary %s -o %t.o
4; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o6; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o
...@@ -19,6 +21,10 @@...@@ -19,6 +21,10 @@
19; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o21; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o
20; RUN: ls %t.cache | count 522; RUN: ls %t.cache | count 5
2123
24; Increase the age of llvmcache-foo, which will give it the oldest time stamp
25; so that it is processed and removed first.
26; RUN: %python -c 'import os,sys,time; t=time.time()-120; os.utime(sys.argv[1],(t,t))' %t.cache/llvmcache-foo
27
22; This should remove it.28; This should remove it.
23; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t3 %t2.o %t.o29; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t3 %t2.o %t.o
24; RUN: ls %t.cache | count 430; RUN: ls %t.cache | count 4
...@@ -31,6 +37,20 @@...@@ -31,6 +37,20 @@
31; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t3 %t2.o %t.o37; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t3 %t2.o %t.o
32; RUN: ls %t.cache | count 338; RUN: ls %t.cache | count 3
3339
40; Check that we remove the least recently used file first.
41; RUN: rm -fr %t.cache
42; RUN: mkdir %t.cache
43; RUN: echo xyz > %t.cache/llvmcache-old
44; RUN: touch -t 198002011200 %t.cache/llvmcache-old
45; RUN: echo xyz > %t.cache/llvmcache-newer
46; RUN: touch -t 198002021200 %t.cache/llvmcache-newer
47; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=3:prune_interval=0s -o %t3 %t2.o %t.o
48; RUN: ls %t.cache | FileCheck %s
49
50; CHECK-NOT: llvmcache-old
51; CHECK: llvmcache-newer
52; CHECK-NOT: llvmcache-old
53
34target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"54target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
35target triple = "x86_64-unknown-linux-gnu"55target triple = "x86_64-unknown-linux-gnu"
3656
deps/lld/test/ELF/lto/data-ordering-lto.s+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8# RUN: echo "pat " >> %t_order_lto.txt8# RUN: echo "pat " >> %t_order_lto.txt
99
10# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out10# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out
11# RUN: llvm-readelf -t %t2.out| FileCheck %s11# RUN: llvm-readelf --symbols %t2.out| FileCheck %s
1212
13# Check that the order is tin -> dipsy -> pat.13# Check that the order is tin -> dipsy -> pat.
1414
deps/lld/test/ELF/lto/defsym.ll+2-2
...@@ -3,14 +3,14 @@...@@ -3,14 +3,14 @@
3; RUN: llvm-as %s -o %t.o3; RUN: llvm-as %s -o %t.o
4; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o4; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o
5; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 -save-temps5; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 -save-temps
6; RUN: llvm-readelf -t %t.so.lto.o | FileCheck --check-prefix=OBJ %s6; RUN: llvm-readelf --symbols %t.so.lto.o | FileCheck --check-prefix=OBJ %s
7; RUN: llvm-objdump -d %t.so | FileCheck %s7; RUN: llvm-objdump -d %t.so | FileCheck %s
88
9; ThinLTO9; ThinLTO
10; RUN: opt -module-summary %s -o %t.o10; RUN: opt -module-summary %s -o %t.o
11; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o11; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o
12; RUN: ld.lld %t.o %t1.o -shared -o %t2.so -defsym=bar2=bar3 -save-temps12; RUN: ld.lld %t.o %t1.o -shared -o %t2.so -defsym=bar2=bar3 -save-temps
13; RUN: llvm-readelf -t %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s13; RUN: llvm-readelf --symbols %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s
14; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN14; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN
1515
16; OBJ: UND bar216; OBJ: UND bar2
deps/lld/test/ELF/lto/dynamic-list.ll+1-1
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
4; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o4; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
5; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s5; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
66
7; CHECK: Name: foo@7; CHECK: Name: foo
8; CHECK-NEXT: Value: 0x10108; CHECK-NEXT: Value: 0x1010
9; CHECK-NEXT: Size: 19; CHECK-NEXT: Size: 1
10; CHECK-NEXT: Binding: Global (0x1)10; CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/lto/emit-llvm.ll created+14
...@@ -0,0 +1,14 @@
1; REQUIRES: x86
2
3; RUN: opt -module-hash -module-summary %s -o %t.o
4; RUN: ld.lld --plugin-opt=emit-llvm -o %t.out.o %t.o
5; RUN: llvm-dis < %t.out.o -o - | FileCheck %s
6
7; CHECK: define internal void @main()
8
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-unknown-linux-gnu"
11
12define void @main() {
13 ret void
14}
deps/lld/test/ELF/lto/libcall-archive.ll+5-1
...@@ -2,10 +2,14 @@...@@ -2,10 +2,14 @@
2; RUN: rm -f %t.a2; RUN: rm -f %t.a
3; RUN: llvm-as -o %t.o %s3; RUN: llvm-as -o %t.o %s
4; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll4; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll
5; RUN: llvm-ar rcs %t.a %t2.o5; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t3.o %S/Inputs/libcall-archive.s
6; RUN: llvm-ar rcs %t.a %t2.o %t3.o
6; RUN: ld.lld -o %t %t.o %t.a7; RUN: ld.lld -o %t %t.o %t.a
7; RUN: llvm-nm %t | FileCheck %s8; RUN: llvm-nm %t | FileCheck %s
9; RUN: ld.lld -o %t2 %t.o --start-lib %t2.o %t3.o --end-lib
10; RUN: llvm-nm %t2 | FileCheck %s
811
12; CHECK-NOT: T __sync_val_compare_and_swap_8
9; CHECK: T _start13; CHECK: T _start
10; CHECK: T memcpy14; CHECK: T memcpy
1115
deps/lld/test/ELF/lto/ltopasses-custom.ll+2-2
...@@ -27,11 +27,11 @@ define void @barrier() {...@@ -27,11 +27,11 @@ define void @barrier() {
27; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \27; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
28; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \28; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \
29; RUN: FileCheck %s --check-prefix=INVALID29; RUN: FileCheck %s --check-prefix=INVALID
30; INVALID: unable to parse pass pipeline description: iamnotapass30; INVALID: unable to parse pass pipeline description 'iamnotapass': unknown pass name 'iamnotapass'
3131
32; Check that invalid AA pipelines are rejected gracefully.32; Check that invalid AA pipelines are rejected gracefully.
33; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \33; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
34; RUN: --lto-newpm-passes=globaldce --lto-aa-pipeline=patatino \34; RUN: --lto-newpm-passes=globaldce --lto-aa-pipeline=patatino \
35; RUN: -shared 2>&1 | \35; RUN: -shared 2>&1 | \
36; RUN: FileCheck %s --check-prefix=INVALIDAA36; RUN: FileCheck %s --check-prefix=INVALIDAA
37; INVALIDAA: unable to parse AA pipeline description: patatino37; INVALIDAA: unknown alias analysis name 'patatino'
deps/lld/test/ELF/lto/opt-remarks.ll+6-4
...@@ -23,9 +23,10 @@...@@ -23,9 +23,10 @@
23; YAML-NEXT: - Callee: tinkywinky23; YAML-NEXT: - Callee: tinkywinky
24; YAML-NEXT: - String: ' inlined into '24; YAML-NEXT: - String: ' inlined into '
25; YAML-NEXT: - Caller: main25; YAML-NEXT: - Caller: main
26; YAML-NEXT: - String: ' with cost='26; YAML-NEXT: - String: ' with '
27; YAML-NEXT: - String: '(cost='
27; YAML-NEXT: - Cost: '0'28; YAML-NEXT: - Cost: '0'
28; YAML-NEXT: - String: ' (threshold='29; YAML-NEXT: - String: ', threshold='
29; YAML-NEXT: - Threshold: '337'30; YAML-NEXT: - Threshold: '337'
30; YAML-NEXT: - String: ')'31; YAML-NEXT: - String: ')'
31; YAML-NEXT: ...32; YAML-NEXT: ...
...@@ -39,9 +40,10 @@...@@ -39,9 +40,10 @@
39; YAML-HOT-NEXT: - Callee: tinkywinky40; YAML-HOT-NEXT: - Callee: tinkywinky
40; YAML-HOT-NEXT: - String: ' inlined into '41; YAML-HOT-NEXT: - String: ' inlined into '
41; YAML-HOT-NEXT: - Caller: main42; YAML-HOT-NEXT: - Caller: main
42; YAML-HOT-NEXT: - String: ' with cost='43; YAML-HOT-NEXT: - String: ' with '
44; YAML-HOT-NEXT: - String: '(cost='
43; YAML-HOT-NEXT: - Cost: '0'45; YAML-HOT-NEXT: - Cost: '0'
44; YAML-HOT-NEXT: - String: ' (threshold='46; YAML-HOT-NEXT: - String: ', threshold='
45; YAML-HOT-NEXT: - Threshold: '337'47; YAML-HOT-NEXT: - Threshold: '337'
46; YAML-HOT-NEXT: - String: ')'48; YAML-HOT-NEXT: - String: ')'
47; YAML-HOT-NEXT: ...49; YAML-HOT-NEXT: ...
deps/lld/test/ELF/lto/ppc64le.ll created+12
...@@ -0,0 +1,12 @@
1; REQUIRES: ppc
2
3; RUN: llvm-as %s -o %t.o
4; RUN: ld.lld %t.o -o %t
5
6target datalayout = "e-m:e-i64:64-n32:64"
7target triple = "powerpc64le-unknown-linux-gnu"
8
9define void @__start() {
10 entry:
11 ret void
12}
deps/lld/test/ELF/lto/r600.ll created+12
...@@ -0,0 +1,12 @@
1; REQUIRES: amdgpu
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld %t.o -o %t
4
5; Make sure the r600 triple is handled
6
7target triple = "r600-mesa-mesa3d"
8target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
9
10define void @_start() {
11 ret void
12}
deps/lld/test/ELF/lto/relocatable.ll+9
...@@ -41,6 +41,15 @@...@@ -41,6 +41,15 @@
41; CHECK-NEXT: Section: .text.foo41; CHECK-NEXT: Section: .text.foo
42; CHECK-NEXT: }42; CHECK-NEXT: }
43; CHECK-NEXT: Symbol {43; CHECK-NEXT: Symbol {
44; CHECK-NEXT: Name:
45; CHECK-NEXT: Value: 0x0
46; CHECK-NEXT: Size: 0
47; CHECK-NEXT: Binding: Local
48; CHECK-NEXT: Type: Section
49; CHECK-NEXT: Other: 0
50; CHECK-NEXT: Section: .llvm_addrsig
51; CHECK-NEXT: }
52; CHECK-NEXT: Symbol {
44; CHECK-NEXT: Name: foo53; CHECK-NEXT: Name: foo
45; CHECK-NEXT: Value: 0x054; CHECK-NEXT: Value: 0x0
46; CHECK-NEXT: Size: 155; CHECK-NEXT: Size: 1
deps/lld/test/ELF/lto/section-name.ll+2-2
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1; REQUIRES: x861; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld %t.o -o %t.so -shared3; RUN: ld.lld %t.o -o %t.so -shared
4; RUN: llvm-readelf -s %t.so | FileCheck %s4; RUN: llvm-readelf -S %t.so | FileCheck %s
5; RUN: ld.lld %t.o -o %t.so -shared --gc-sections5; RUN: ld.lld %t.o -o %t.so -shared --gc-sections
6; RUN: llvm-readelf -s %t.so | FileCheck --check-prefix=GC %s6; RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=GC %s
77
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9target triple = "x86_64-unknown-linux-gnu"9target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/shlib-undefined.ll+1-1
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
6; RUN: ld.lld -o %t %t.o %t2.so6; RUN: ld.lld -o %t %t.o %t2.so
7; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s7; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
88
9; CHECK: Name: __progname@9; CHECK: Name: __progname
10; CHECK-NEXT: Value: 0x20101010; CHECK-NEXT: Value: 0x201010
11; CHECK-NEXT: Size: 111; CHECK-NEXT: Size: 1
12; CHECK-NEXT: Binding: Global (0x1)12; CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/lto/symbol-ordering-lto.s+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8# RUN: echo "pat " >> %t_order_lto.txt8# RUN: echo "pat " >> %t_order_lto.txt
99
10# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out10# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out
11# RUN: llvm-readelf -t %t2.out| FileCheck %s11# RUN: llvm-readelf --symbols %t2.out| FileCheck %s
1212
13# Check that the order is tin -> _start -> pat.13# Check that the order is tin -> _start -> pat.
1414
deps/lld/test/ELF/lto/thinlto-obj-path.ll+2-1
...@@ -7,7 +7,8 @@...@@ -7,7 +7,8 @@
7; RUN: rm -f %t4.o7; RUN: rm -f %t4.o
8; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t38; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3
9; RUN: llvm-readobj -h %t4.o | FileCheck %s9; RUN: llvm-readobj -h %t4.o | FileCheck %s
10; RUN: llvm-nm %t4.o | count 010; RUN: llvm-nm %t4.o 2>&1 | FileCheck %s -check-prefix=NO-SYMBOLS
11; NO-SYMBOLS: no symbols
1112
12; CHECK: Format: ELF64-x86-6413; CHECK: Format: ELF64-x86-64
1314
deps/lld/test/ELF/lto/thinlto-object-suffix-replace.ll+6-6
...@@ -29,12 +29,12 @@...@@ -29,12 +29,12 @@
29; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR129; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR1
30; ERR1: --plugin-opt=thinlto-object-suffix-replace= expects 'old;new' format, but got abc:def30; ERR1: --plugin-opt=thinlto-object-suffix-replace= expects 'old;new' format, but got abc:def
3131
32; Ensure lld generates error if old suffix doesn't exist in file name32; If filename does not end with old suffix, no suffix change should occur,
33; RUN: rm -f %t1.o33; so ".thinlto.bc" will simply be appended to the input file name.
34; RUN: not ld.lld --plugin-opt=thinlto-index-only \34; RUN: rm -f %t1.thinlink.bc.thinlto.bc
35; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \35; RUN: ld.lld --plugin-opt=thinlto-index-only \
36; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR236; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc -o /dev/null
37; ERR2: error: -thinlto-object-suffix-replace=.abc;.o was given, but {{.*}} does not end with the suffix37; RUN: ls %t1.thinlink.bc.thinlto.bc
3838
39target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"39target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
40target triple = "x86_64-unknown-linux-gnu"40target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/undefined-puts.ll+1-1
...@@ -25,4 +25,4 @@ declare i32 @printf(i8*, ...)...@@ -25,4 +25,4 @@ declare i32 @printf(i8*, ...)
2525
26; CHECK: DynamicSymbols [26; CHECK: DynamicSymbols [
27; CHECK: Symbol {27; CHECK: Symbol {
28; CHECK: Name: puts@28; CHECK: Name: puts
deps/lld/test/ELF/lto/version-script.ll+1-1
...@@ -21,7 +21,7 @@ define void @bar() {...@@ -21,7 +21,7 @@ define void @bar() {
2121
22; DSO: DynamicSymbols [22; DSO: DynamicSymbols [
23; DSO: Symbol {23; DSO: Symbol {
24; DSO: Name: @ (0)24; DSO: Name:
25; DSO: Value: 0x025; DSO: Value: 0x0
26; DSO: Size: 026; DSO: Size: 0
27; DSO: Binding: Local27; DSO: Binding: Local
deps/lld/test/ELF/lto/wrap-2.ll+6-2
...@@ -28,11 +28,15 @@...@@ -28,11 +28,15 @@
28; THIN-NEXT: jmp{{.*}}<bar>28; THIN-NEXT: jmp{{.*}}<bar>
2929
30; Check that bar and __wrap_bar retain their original binding.30; Check that bar and __wrap_bar retain their original binding.
31; BIND: Name: __wrap_bar31; BIND: Name: bar
32; BIND-NEXT: Value:32; BIND-NEXT: Value:
33; BIND-NEXT: Size:33; BIND-NEXT: Size:
34; BIND-NEXT: Binding: Local34; BIND-NEXT: Binding: Local
35; BIND: Name: bar35; BIND: Name: __real_bar
36; BIND-NEXT: Value:
37; BIND-NEXT: Size:
38; BIND-NEXT: Binding: Local
39; BIND: Name: __wrap_bar
36; BIND-NEXT: Value:40; BIND-NEXT: Value:
37; BIND-NEXT: Size:41; BIND-NEXT: Size:
38; BIND-NEXT: Binding: Local42; BIND-NEXT: Binding: Local
deps/lld/test/ELF/map-file-i686.s+12-12
...@@ -7,15 +7,15 @@...@@ -7,15 +7,15 @@
7_start:7_start:
8 nop8 nop
99
10// CHECK: VMA LMA Size Align Out In Symbol10// CHECK: VMA LMA Size Align Out In Symbol
11// CHECK-NEXT: 11000 11000 1 4 .text11// CHECK-NEXT: 401000 401000 1 4 .text
12// CHECK-NEXT: 11000 11000 1 4 {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)12// CHECK-NEXT: 401000 401000 1 4 {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)
13// CHECK-NEXT: 11000 11000 0 1 _start13// CHECK-NEXT: 401000 401000 0 1 _start
14// CHECK-NEXT: 0 0 8 1 .comment14// CHECK-NEXT: 0 0 8 1 .comment
15// CHECK-NEXT: 0 0 8 1 <internal>:(.comment)15// CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
16// CHECK-NEXT: 0 0 20 4 .symtab16// CHECK-NEXT: 0 0 20 4 .symtab
17// CHECK-NEXT: 0 0 20 4 <internal>:(.symtab)17// CHECK-NEXT: 0 0 20 4 <internal>:(.symtab)
18// CHECK-NEXT: 0 0 2a 1 .shstrtab18// CHECK-NEXT: 0 0 2a 1 .shstrtab
19// CHECK-NEXT: 0 0 2a 1 <internal>:(.shstrtab)19// CHECK-NEXT: 0 0 2a 1 <internal>:(.shstrtab)
20// CHECK-NEXT: 0 0 8 1 .strtab20// CHECK-NEXT: 0 0 8 1 .strtab
21// CHECK-NEXT: 0 0 8 1 <internal>:(.strtab)21// CHECK-NEXT: 0 0 8 1 <internal>:(.strtab)
deps/lld/test/ELF/merge-string-error.s+1-1
...@@ -8,4 +8,4 @@...@@ -8,4 +8,4 @@
8 .data8 .data
9 .long .rodata.str1.1 + 49 .long .rodata.str1.1 + 4
1010
11// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): entry is past the end of the section11// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): offset is outside the section
deps/lld/test/ELF/mergeable-errors.s created+8
...@@ -0,0 +1,8 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: not ld.lld %t.o -o %t1 2>&1 | FileCheck %s
4
5# CHECK: error: {{.*}}.o:(.mergeable): string is not null terminated
6
7.section .mergeable,"MS",@progbits,2
8 .short 0x1122
deps/lld/test/ELF/mips-32.s+2-2
...@@ -41,8 +41,8 @@ v2:...@@ -41,8 +41,8 @@ v2:
41# ^-- v2+4 ^-- v141# ^-- v2+4 ^-- v1
4242
43# SYM: SYMBOL TABLE:43# SYM: SYMBOL TABLE:
44# SYM: 00020000 l .data 00000004 v144# SYM: 00020000 l O .data 00000004 v1
45# SYM: 00020004 g .data 00000008 v245# SYM: 00020004 g O .data 00000008 v2
4646
47# REL: Relocations [47# REL: Relocations [
48# REL-NEXT: Section (7) .rel.dyn {48# REL-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-64.s+2-2
...@@ -25,8 +25,8 @@ v2:...@@ -25,8 +25,8 @@ v2:
2525
2626
27# SYM: SYMBOL TABLE:27# SYM: SYMBOL TABLE:
28# SYM: 00020000 l .data 00000004 v128# SYM: 00020000 l O .data 00000004 v1
29# SYM: 00020008 g .data 00000008 v229# SYM: 00020008 g O .data 00000008 v2
3030
31# CHECK: Relocations [31# CHECK: Relocations [
32# CHECK-NEXT: Section (7) .rel.dyn {32# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-dynamic.s+3-3
...@@ -97,9 +97,9 @@...@@ -97,9 +97,9 @@
97# DSO-NEXT: Size: 897# DSO-NEXT: Size: 8
98# DSO: ]98# DSO: ]
99# DSO: DynamicSymbols [99# DSO: DynamicSymbols [
100# DSO: Name: @100# DSO: Name:
101# DSO: Name: __start@101# DSO: Name: __start
102# DSO: Name: _foo@102# DSO: Name: _foo
103# DSO: ]103# DSO: ]
104# DSO: DynamicSection [104# DSO: DynamicSection [
105# DSO-NEXT: Tag Type Name/Value105# DSO-NEXT: Tag Type Name/Value
deps/lld/test/ELF/mips-dynsym-sort.s+3-3
...@@ -36,7 +36,7 @@ __start:...@@ -36,7 +36,7 @@ __start:
36# the MIPS rules. v2 comes first as it is not in the GOT.36# the MIPS rules. v2 comes first as it is not in the GOT.
37# v1 and v3 are sorted according to their order in the GOT.37# v1 and v3 are sorted according to their order in the GOT.
38# CHECK: DynamicSymbols [38# CHECK: DynamicSymbols [
39# CHECK: Name: v2@39# CHECK: Name: v2
40# CHECK: Name: v3@40# CHECK: Name: v3
41# CHECK: Name: v1@41# CHECK: Name: v1
42# CHECK: ]42# CHECK: ]
deps/lld/test/ELF/mips-gnu-hash.s+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o7# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
8# RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o /dev/null 2>&1 | FileCheck %s8# RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o /dev/null 2>&1 | FileCheck %s
99
10# CHECK: the .gnu.hash section is not compatible with the MIPS target.10# CHECK: the .gnu.hash section is not compatible with the MIPS target
1111
12 .globl __start12 .globl __start
13__start:13__start:
deps/lld/test/ELF/mips-got-and-copy.s+2-2
...@@ -32,7 +32,7 @@...@@ -32,7 +32,7 @@
32# CHECK-NEXT: Value: 0x[[DATA0]]32# CHECK-NEXT: Value: 0x[[DATA0]]
33# CHECK-NEXT: Type: Object33# CHECK-NEXT: Type: Object
34# CHECK-NEXT: Section: .bss34# CHECK-NEXT: Section: .bss
35# CHECK-NEXT: Name: data0@35# CHECK-NEXT: Name: data0
36# CHECK-NEXT: }36# CHECK-NEXT: }
37# CHECK-NEXT: Entry {37# CHECK-NEXT: Entry {
38# CHECK-NEXT: Address:38# CHECK-NEXT: Address:
...@@ -41,7 +41,7 @@...@@ -41,7 +41,7 @@
41# CHECK-NEXT: Value: 0x[[DATA1]]41# CHECK-NEXT: Value: 0x[[DATA1]]
42# CHECK-NEXT: Type: Object42# CHECK-NEXT: Type: Object
43# CHECK-NEXT: Section: .bss43# CHECK-NEXT: Section: .bss
44# CHECK-NEXT: Name: data1@44# CHECK-NEXT: Name: data1
45# CHECK-NEXT: }45# CHECK-NEXT: }
46# CHECK-NEXT: ]46# CHECK-NEXT: ]
47# CHECK-NEXT: Number of TLS and multi-GOT entries: 047# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
deps/lld/test/ELF/mips-got-extsym.s+1-1
...@@ -43,7 +43,7 @@...@@ -43,7 +43,7 @@
43# CHECK-NEXT: Value: 0x043# CHECK-NEXT: Value: 0x0
44# CHECK-NEXT: Type: None44# CHECK-NEXT: Type: None
45# CHECK-NEXT: Section: Undefined45# CHECK-NEXT: Section: Undefined
46# CHECK-NEXT: Name: _foo@46# CHECK-NEXT: Name: _foo
47# CHECK-NEXT: }47# CHECK-NEXT: }
48# CHECK-NEXT: ]48# CHECK-NEXT: ]
4949
deps/lld/test/ELF/mips-got-relocs.s+2-2
...@@ -48,7 +48,7 @@ v1:...@@ -48,7 +48,7 @@ v1:
48# EXE_SYM: SYMBOL TABLE:48# EXE_SYM: SYMBOL TABLE:
49# EXE_SYM: 00038000 .got 00000000 .hidden _gp49# EXE_SYM: 00038000 .got 00000000 .hidden _gp
50# ^-- .got + GP offset (0x7ff0)50# ^-- .got + GP offset (0x7ff0)
51# EXE_SYM: 00030000 g .data 00000004 v151# EXE_SYM: 00030000 g O .data 00000004 v1
5252
5353
54# EXE_GOT_BE: Contents of section .got:54# EXE_GOT_BE: Contents of section .got:
...@@ -72,7 +72,7 @@ v1:...@@ -72,7 +72,7 @@ v1:
72# DSO_SYM: SYMBOL TABLE:72# DSO_SYM: SYMBOL TABLE:
73# DSO_SYM: 00028000 .got 00000000 .hidden _gp73# DSO_SYM: 00028000 .got 00000000 .hidden _gp
74# ^-- .got + GP offset (0x7ff0)74# ^-- .got + GP offset (0x7ff0)
75# DSO_SYM: 00020000 g .data 00000004 v175# DSO_SYM: 00020000 g O .data 00000004 v1
7676
77# DSO_GOT_BE: Contents of section .got:77# DSO_GOT_BE: Contents of section .got:
78# DSO_GOT_BE: 20010 00000000 80000000 0002000078# DSO_GOT_BE: 20010 00000000 80000000 00020000
deps/lld/test/ELF/mips-got16-relocatable.s+2-6
...@@ -14,9 +14,7 @@...@@ -14,9 +14,7 @@
14# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data14# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
15# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 015# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 0
16# OBJ-NEXT: 00000004: R_MIPS_LO16 .data16# OBJ-NEXT: 00000004: R_MIPS_LO16 .data
17# OBJ-NEXT: 8: ef ef ef ef <unknown>17# OBJ: 10: 8f 99 00 00 lw $25, 0($gp)
18# OBJ-NEXT: c: ef ef ef ef <unknown>
19# OBJ-NEXT: 10: 8f 99 00 00 lw $25, 0($gp)
20# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data18# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data
21# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 1619# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 16
22# OBJ-NEXT: 00000014: R_MIPS_LO16 .data20# OBJ-NEXT: 00000014: R_MIPS_LO16 .data
...@@ -25,9 +23,7 @@...@@ -25,9 +23,7 @@
25# SO-NEXT: .text:23# SO-NEXT: .text:
26# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)24# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
27# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 025# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
28# SO-NEXT: 10008: ef ef ef ef <unknown>26# SO: 10010: 8f 99 80 18 lw $25, -32744($gp)
29# SO-NEXT: 1000c: ef ef ef ef <unknown>
30# SO-NEXT: 10010: 8f 99 80 18 lw $25, -32744($gp)
31# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 1627# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 16
3228
33 .text29 .text
deps/lld/test/ELF/mips-got16.s+1-1
...@@ -96,7 +96,7 @@...@@ -96,7 +96,7 @@
96# GOT-NEXT: Value: 0x096# GOT-NEXT: Value: 0x0
97# GOT-NEXT: Type: None97# GOT-NEXT: Type: None
98# GOT-NEXT: Section: Undefined98# GOT-NEXT: Section: Undefined
99# GOT-NEXT: Name: foo@99# GOT-NEXT: Name: foo
100# GOT-NEXT: }100# GOT-NEXT: }
101# GOT-NEXT: ]101# GOT-NEXT: ]
102# GOT-NEXT: Number of TLS and multi-GOT entries: 0102# GOT-NEXT: Number of TLS and multi-GOT entries: 0
deps/lld/test/ELF/mips-hilo.s+3-3
...@@ -47,6 +47,6 @@ g1:...@@ -47,6 +47,6 @@ g1:
47# ^-- %lo(l1-4)47# ^-- %lo(l1-4)
4848
49# CHECK: SYMBOL TABLE:49# CHECK: SYMBOL TABLE:
50# CHECK: 0030000 l .data 00000004 l150# CHECK: 0030000 l O .data 00000004 l1
51# CHECK: 0020000 .text 00000000 __start51# CHECK: 0020000 .text 00000000 __start
52# CHECK: 0030004 g .data 00000004 g152# CHECK: 0030004 g O .data 00000004 g1
deps/lld/test/ELF/mips-mgot.s+7-7
...@@ -18,13 +18,13 @@...@@ -18,13 +18,13 @@
18# CHECK-NEXT: 60040 00000000 00000000 0000000018# CHECK-NEXT: 60040 00000000 00000000 00000000
1919
20# CHECK: SYMBOL TABLE:20# CHECK: SYMBOL TABLE:
21# CHECK: 00000000 l .tdata 00000000 loc021# CHECK: 00000000 l O .tdata 00000000 loc0
22# CHECK: 00010000 .text 00000000 foo022# CHECK: 00010000 .text 00000000 foo0
23# CHECK: 00000000 g .tdata 00000000 tls023# CHECK: 00000000 g O .tdata 00000000 tls0
24# CHECK: 00010020 .text 00000000 foo124# CHECK: 00010020 .text 00000000 foo1
25# CHECK: 00000004 g .tdata 00000000 tls125# CHECK: 00000004 g O .tdata 00000000 tls1
26# CHECK: 00010030 .text 00000000 foo226# CHECK: 00010030 .text 00000000 foo2
27# CHECK: 00000008 g .tdata 00000000 tls227# CHECK: 00000008 g O .tdata 00000000 tls2
2828
29# GOT: Relocations [29# GOT: Relocations [
30# GOT-NEXT: Section (7) .rel.dyn {30# GOT-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-micro-jal.s+3-9
...@@ -57,9 +57,7 @@...@@ -57,9 +57,7 @@
57# EB-NEXT: 20022: 45 f9 jalrs16 $2557# EB-NEXT: 20022: 45 f9 jalrs16 $25
58# EB-NEXT: 20024: 0f 83 move $gp, $358# EB-NEXT: 20024: 0f 83 move $gp, $3
59# EB-NEXT: 20026: 0c 00 nop59# EB-NEXT: 20026: 0c 00 nop
60# EB-NEXT: 20028: 00 00 00 00 nop60# EB-NEXT: ...
61# EB-NEXT: 2002c: 00 00 00 00 nop
62
63# EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 6550061# EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 65500
64# EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2)62# EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2)
65# EB-NEXT: 20038: 45 99 jr16 $2563# EB-NEXT: 20038: 45 99 jr16 $25
...@@ -76,9 +74,7 @@...@@ -76,9 +74,7 @@
76# EL-NEXT: 20022: f9 45 jalrs16 $2574# EL-NEXT: 20022: f9 45 jalrs16 $25
77# EL-NEXT: 20024: 83 0f move $gp, $375# EL-NEXT: 20024: 83 0f move $gp, $3
78# EL-NEXT: 20026: 00 0c nop76# EL-NEXT: 20026: 00 0c nop
79# EL-NEXT: 20028: 00 00 00 00 nop77# EL-NEXT: ...
80# EL-NEXT: 2002c: 00 00 00 00 nop
81
82# EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 6550078# EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 65500
83# EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2)79# EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2)
84# EL-NEXT: 20038: 99 45 jr16 $2580# EL-NEXT: 20038: 99 45 jr16 $25
...@@ -127,9 +123,7 @@...@@ -127,9 +123,7 @@
127# MIXED-NEXT: 20032: 45 f9 jalrs16 $25123# MIXED-NEXT: 20032: 45 f9 jalrs16 $25
128# MIXED-NEXT: 20034: 0f 83 move $gp, $3124# MIXED-NEXT: 20034: 0f 83 move $gp, $3
129# MIXED-NEXT: 20036: 0c 00 nop125# MIXED-NEXT: 20036: 0c 00 nop
130# MIXED-NEXT: 20038: 00 00 00 00 nop126# MIXED-NEXT: ...
131# MIXED-NEXT: 2003c: 00 00 00 00 nop
132
133# MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484127# MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484
134# MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2)128# MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2)
135# MIXED-NEXT: 20048: 45 99 jr16 $25129# MIXED-NEXT: 20048: 45 99 jr16 $25
deps/lld/test/ELF/mips-micro-plt.s+1-1
...@@ -80,7 +80,7 @@...@@ -80,7 +80,7 @@
80# CHECK-NEXT: Value: 0x2004180# CHECK-NEXT: Value: 0x20041
81# CHECK-NEXT: Type: Function81# CHECK-NEXT: Type: Function
82# CHECK-NEXT: Section: Undefined82# CHECK-NEXT: Section: Undefined
83# CHECK-NEXT: Name: foo0@83# CHECK-NEXT: Name: foo0
84# CHECK-NEXT: }84# CHECK-NEXT: }
85# CHECK-NEXT: ]85# CHECK-NEXT: ]
86# CHECK-NEXT: }86# CHECK-NEXT: }
deps/lld/test/ELF/mips-npic-call-pic-os.s+18-17
...@@ -19,37 +19,37 @@...@@ -19,37 +19,37 @@
19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
20# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 3220# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
21# CHECK-NEXT: 2000c: 00 00 00 00 nop21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22
22# CHECK: __LA25Thunk_foo1b:23# CHECK: __LA25Thunk_foo1b:
23# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 224# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
24# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>25# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
25# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 3626# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
26# CHECK-NEXT: 2001c: 00 00 00 00 nop27# CHECK-NEXT: 2001c: 00 00 00 00 nop
28
27# CHECK: foo1a:29# CHECK: foo1a:
28# CHECK-NEXT: 20020: 00 00 00 00 nop30# CHECK-NEXT: 20020: 00 00 00 00 nop
31
29# CHECK: foo1b:32# CHECK: foo1b:
30# CHECK-NEXT: 20024: 00 00 00 00 nop33# CHECK-NEXT: 20024: 00 00 00 00 nop
34
31# CHECK: __LA25Thunk_foo2:35# CHECK: __LA25Thunk_foo2:
32# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 236# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>37# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
34# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 6438# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
35# CHECK-NEXT: 20034: 00 00 00 00 nop39# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>40
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
38# CHECK: foo2:41# CHECK: foo2:
39# CHECK-NEXT: 20040: 00 00 00 00 nop42# CHECK-NEXT: 20040: 00 00 00 00 nop
43
40# CHECK: __LA25Thunk_fpic:44# CHECK: __LA25Thunk_fpic:
41# CHECK-NEXT: 20044: 3c 19 00 02 lui $25, 245# CHECK-NEXT: 20044: 3c 19 00 02 lui $25, 2
42# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>46# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>
43# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 9647# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 96
44# CHECK-NEXT: 20050: 00 00 00 00 nop48# CHECK-NEXT: 20050: 00 00 00 00 nop
45# CHECK-NEXT: 20054: ef ef ef ef <unknown>49
46# CHECK-NEXT: 20058: ef ef ef ef <unknown>
47# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
48# CHECK: fpic:50# CHECK: fpic:
49# CHECK-NEXT: 20060: 00 00 00 00 nop51# CHECK-NEXT: 20060: 00 00 00 00 nop
50# CHECK-NEXT: 20064: ef ef ef ef <unknown>52
51# CHECK-NEXT: 20068: ef ef ef ef <unknown>
52# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
53# CHECK: fnpic:53# CHECK: fnpic:
54# CHECK-NEXT: 20070: 00 00 00 00 nop54# CHECK-NEXT: 20070: 00 00 00 00 nop
55# CHECK-NEXT: Disassembly of section differentos:55# CHECK-NEXT: Disassembly of section differentos:
...@@ -79,40 +79,41 @@...@@ -79,40 +79,41 @@
79# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>79# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
80# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 3280# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
81# REVERSE-NEXT: 2000c: 00 00 00 00 nop81# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82
82# REVERSE: __LA25Thunk_foo1b:83# REVERSE: __LA25Thunk_foo1b:
83# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 284# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
84# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>85# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
85# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 3686# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
86# REVERSE-NEXT: 2001c: 00 00 00 00 nop87# REVERSE-NEXT: 2001c: 00 00 00 00 nop
88
87# REVERSE: foo1a:89# REVERSE: foo1a:
88# REVERSE-NEXT: 20020: 00 00 00 00 nop90# REVERSE-NEXT: 20020: 00 00 00 00 nop
91
89# REVERSE: foo1b:92# REVERSE: foo1b:
90# REVERSE-NEXT: 20024: 00 00 00 00 nop93# REVERSE-NEXT: 20024: 00 00 00 00 nop
94
91# REVERSE: __LA25Thunk_foo2:95# REVERSE: __LA25Thunk_foo2:
92# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 296# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
93# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>97# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
94# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 6498# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
95# REVERSE-NEXT: 20034: 00 00 00 00 nop99# REVERSE-NEXT: 20034: 00 00 00 00 nop
96# REVERSE-NEXT: 20038: ef ef ef ef <unknown>100
97# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
98# REVERSE: foo2:101# REVERSE: foo2:
99# REVERSE-NEXT: 20040: 00 00 00 00 nop102# REVERSE-NEXT: 20040: 00 00 00 00 nop
100# REVERSE-NEXT: 20044: ef ef ef ef <unknown>103
101# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
102# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
103# REVERSE: __LA25Thunk_fpic:104# REVERSE: __LA25Thunk_fpic:
104# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2105# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2
105# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>106# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>
106# REVERSE-NEXT: 20058: 27 39 00 60 addiu $25, $25, 96107# REVERSE-NEXT: 20058: 27 39 00 60 addiu $25, $25, 96
107# REVERSE-NEXT: 2005c: 00 00 00 00 nop108# REVERSE-NEXT: 2005c: 00 00 00 00 nop
109
108# REVERSE: fpic:110# REVERSE: fpic:
109# REVERSE-NEXT: 20060: 00 00 00 00 nop111# REVERSE-NEXT: 20060: 00 00 00 00 nop
110# REVERSE-NEXT: 20064: ef ef ef ef <unknown>112
111# REVERSE-NEXT: 20068: ef ef ef ef <unknown>
112# REVERSE-NEXT: 2006c: ef ef ef ef <unknown>
113# REVERSE: fnpic:113# REVERSE: fnpic:
114# REVERSE-NEXT: 20070: 00 00 00 00 nop114# REVERSE-NEXT: 20070: 00 00 00 00 nop
115# REVERSE-NEXT: Disassembly of section differentos:115
116# REVERSE: Disassembly of section differentos:
116# REVERSE-NEXT: __start:117# REVERSE-NEXT: __start:
117# REVERSE-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>118# REVERSE-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
118# REVERSE-NEXT: 20078: 00 00 00 00 nop119# REVERSE-NEXT: 20078: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic-script.s+29-85
...@@ -19,91 +19,28 @@...@@ -19,91 +19,28 @@
19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
20# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 3220# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
21# CHECK-NEXT: 2000c: 00 00 00 00 nop21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22
22# CHECK: __LA25Thunk_foo1b:23# CHECK: __LA25Thunk_foo1b:
23# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 224# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
24# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>25# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
25# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 3626# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
26# CHECK-NEXT: 2001c: 00 00 00 00 nop27# CHECK-NEXT: 2001c: 00 00 00 00 nop
28
27# CHECK: foo1a:29# CHECK: foo1a:
28# CHECK-NEXT: 20020: 00 00 00 00 nop30# CHECK-NEXT: 20020: 00 00 00 00 nop
31
29# CHECK: foo1b:32# CHECK: foo1b:
30# CHECK-NEXT: 20024: 00 00 00 00 nop33# CHECK-NEXT: 20024: 00 00 00 00 nop
34
31# CHECK: __LA25Thunk_foo2:35# CHECK: __LA25Thunk_foo2:
32# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 236# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>37# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
34# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 6438# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
35# CHECK-NEXT: 20034: 00 00 00 00 nop39# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>40
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
38# CHECK: foo2:41# CHECK: foo2:
39# CHECK-NEXT: 20040: 00 00 00 00 nop42# CHECK-NEXT: 20040: 00 00 00 00 nop
40# CHECK-NEXT: 20044: ef ef ef ef <unknown>43
41# CHECK-NEXT: 20048: ef ef ef ef <unknown>
42# CHECK-NEXT: 2004c: ef ef ef ef <unknown>
43# CHECK-NEXT: 20050: ef ef ef ef <unknown>
44# CHECK-NEXT: 20054: ef ef ef ef <unknown>
45# CHECK-NEXT: 20058: ef ef ef ef <unknown>
46# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
47# CHECK-NEXT: 20060: ef ef ef ef <unknown>
48# CHECK-NEXT: 20064: ef ef ef ef <unknown>
49# CHECK-NEXT: 20068: ef ef ef ef <unknown>
50# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
51# CHECK-NEXT: 20070: ef ef ef ef <unknown>
52# CHECK-NEXT: 20074: ef ef ef ef <unknown>
53# CHECK-NEXT: 20078: ef ef ef ef <unknown>
54# CHECK-NEXT: 2007c: ef ef ef ef <unknown>
55# CHECK-NEXT: 20080: ef ef ef ef <unknown>
56# CHECK-NEXT: 20084: ef ef ef ef <unknown>
57# CHECK-NEXT: 20088: ef ef ef ef <unknown>
58# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
59# CHECK-NEXT: 20090: ef ef ef ef <unknown>
60# CHECK-NEXT: 20094: ef ef ef ef <unknown>
61# CHECK-NEXT: 20098: ef ef ef ef <unknown>
62# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
63# CHECK-NEXT: 200a0: ef ef ef ef <unknown>
64# CHECK-NEXT: 200a4: ef ef ef ef <unknown>
65# CHECK-NEXT: 200a8: ef ef ef ef <unknown>
66# CHECK-NEXT: 200ac: ef ef ef ef <unknown>
67# CHECK-NEXT: 200b0: ef ef ef ef <unknown>
68# CHECK-NEXT: 200b4: ef ef ef ef <unknown>
69# CHECK-NEXT: 200b8: ef ef ef ef <unknown>
70# CHECK-NEXT: 200bc: ef ef ef ef <unknown>
71# CHECK-NEXT: 200c0: ef ef ef ef <unknown>
72# CHECK-NEXT: 200c4: ef ef ef ef <unknown>
73# CHECK-NEXT: 200c8: ef ef ef ef <unknown>
74# CHECK-NEXT: 200cc: ef ef ef ef <unknown>
75# CHECK-NEXT: 200d0: ef ef ef ef <unknown>
76# CHECK-NEXT: 200d4: ef ef ef ef <unknown>
77# CHECK-NEXT: 200d8: ef ef ef ef <unknown>
78# CHECK-NEXT: 200dc: ef ef ef ef <unknown>
79# CHECK-NEXT: 200e0: ef ef ef ef <unknown>
80# CHECK-NEXT: 200e4: ef ef ef ef <unknown>
81# CHECK-NEXT: 200e8: ef ef ef ef <unknown>
82# CHECK-NEXT: 200ec: ef ef ef ef <unknown>
83# CHECK-NEXT: 200f0: ef ef ef ef <unknown>
84# CHECK-NEXT: 200f4: ef ef ef ef <unknown>
85# CHECK-NEXT: 200f8: ef ef ef ef <unknown>
86# CHECK-NEXT: 200fc: ef ef ef ef <unknown>
87# CHECK-NEXT: 20100: ef ef ef ef <unknown>
88# CHECK-NEXT: 20104: ef ef ef ef <unknown>
89# CHECK-NEXT: 20108: ef ef ef ef <unknown>
90# CHECK-NEXT: 2010c: ef ef ef ef <unknown>
91# CHECK-NEXT: 20110: ef ef ef ef <unknown>
92# CHECK-NEXT: 20114: ef ef ef ef <unknown>
93# CHECK-NEXT: 20118: ef ef ef ef <unknown>
94# CHECK-NEXT: 2011c: ef ef ef ef <unknown>
95# CHECK-NEXT: 20120: ef ef ef ef <unknown>
96# CHECK-NEXT: 20124: ef ef ef ef <unknown>
97# CHECK-NEXT: 20128: ef ef ef ef <unknown>
98# CHECK-NEXT: 2012c: ef ef ef ef <unknown>
99# CHECK-NEXT: 20130: ef ef ef ef <unknown>
100# CHECK-NEXT: 20134: ef ef ef ef <unknown>
101# CHECK-NEXT: 20138: ef ef ef ef <unknown>
102# CHECK-NEXT: 2013c: ef ef ef ef <unknown>
103# CHECK-NEXT: 20140: ef ef ef ef <unknown>
104# CHECK-NEXT: 20144: ef ef ef ef <unknown>
105# CHECK-NEXT: 20148: ef ef ef ef <unknown>
106# CHECK-NEXT: 2014c: ef ef ef ef <unknown>
107# CHECK: __start:44# CHECK: __start:
108# CHECK-NEXT: 20150: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>45# CHECK-NEXT: 20150: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
109# CHECK-NEXT: 20154: 00 00 00 00 nop46# CHECK-NEXT: 20154: 00 00 00 00 nop
...@@ -117,16 +54,16 @@...@@ -117,16 +54,16 @@
117# CHECK-NEXT: 20174: 00 00 00 00 nop54# CHECK-NEXT: 20174: 00 00 00 00 nop
118# CHECK-NEXT: 20178: 0c 00 80 68 jal 131488 <fnpic>55# CHECK-NEXT: 20178: 0c 00 80 68 jal 131488 <fnpic>
119# CHECK-NEXT: 2017c: 00 00 00 00 nop56# CHECK-NEXT: 2017c: 00 00 00 00 nop
57
120# CHECK: __LA25Thunk_fpic:58# CHECK: __LA25Thunk_fpic:
121# CHECK-NEXT: 20180: 3c 19 00 02 lui $25, 259# CHECK-NEXT: 20180: 3c 19 00 02 lui $25, 2
122# CHECK-NEXT: 20184: 08 00 80 64 j 131472 <fpic>60# CHECK-NEXT: 20184: 08 00 80 64 j 131472 <fpic>
123# CHECK-NEXT: 20188: 27 39 01 90 addiu $25, $25, 40061# CHECK-NEXT: 20188: 27 39 01 90 addiu $25, $25, 400
124# CHECK-NEXT: 2018c: 00 00 00 00 nop62# CHECK-NEXT: 2018c: 00 00 00 00 nop
63
125# CHECK: fpic:64# CHECK: fpic:
126# CHECK-NEXT: 20190: 00 00 00 00 nop65# CHECK-NEXT: 20190: 00 00 00 00 nop
127# CHECK-NEXT: 20194: ef ef ef ef <unknown>66
128# CHECK-NEXT: 20198: ef ef ef ef <unknown>
129# CHECK-NEXT: 2019c: ef ef ef ef <unknown>
130# CHECK: fnpic:67# CHECK: fnpic:
131# CHECK-NEXT: 201a0: 00 00 00 00 nop68# CHECK-NEXT: 201a0: 00 00 00 00 nop
13269
...@@ -145,6 +82,7 @@ __start:...@@ -145,6 +82,7 @@ __start:
145# RUN: echo "SECTIONS { .text 0x20000 : { *(.text) } }" > %t2.script82# RUN: echo "SECTIONS { .text 0x20000 : { *(.text) } }" > %t2.script
146# RUN: ld.lld --script %t2.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t2.exe83# RUN: ld.lld --script %t2.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t2.exe
147# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s84# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s
85
148# ORPH1: Disassembly of section .text:86# ORPH1: Disassembly of section .text:
149# ORPH1-NEXT: __start:87# ORPH1-NEXT: __start:
150# ORPH1-NEXT: 20000: 0c 00 80 15 jal 131156 <__LA25Thunk_foo1a>88# ORPH1-NEXT: 20000: 0c 00 80 15 jal 131156 <__LA25Thunk_foo1a>
...@@ -159,42 +97,43 @@ __start:...@@ -159,42 +97,43 @@ __start:
159# ORPH1-NEXT: 20024: 00 00 00 00 nop97# ORPH1-NEXT: 20024: 00 00 00 00 nop
160# ORPH1-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>98# ORPH1-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
161# ORPH1-NEXT: 2002c: 00 00 00 00 nop99# ORPH1-NEXT: 2002c: 00 00 00 00 nop
100
162# ORPH1: __LA25Thunk_fpic:101# ORPH1: __LA25Thunk_fpic:
163# ORPH1-NEXT: 20030: 3c 19 00 02 lui $25, 2102# ORPH1-NEXT: 20030: 3c 19 00 02 lui $25, 2
164# ORPH1-NEXT: 20034: 08 00 80 10 j 131136 <fpic>103# ORPH1-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
165# ORPH1-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64104# ORPH1-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
166# ORPH1-NEXT: 2003c: 00 00 00 00 nop105# ORPH1-NEXT: 2003c: 00 00 00 00 nop
106
167# ORPH1: fpic:107# ORPH1: fpic:
168# ORPH1-NEXT: 20040: 00 00 00 00 nop108# ORPH1-NEXT: 20040: 00 00 00 00 nop
169# ORPH1-NEXT: 20044: ef ef ef ef <unknown>109
170# ORPH1-NEXT: 20048: ef ef ef ef <unknown>
171# ORPH1-NEXT: 2004c: ef ef ef ef <unknown>
172# ORPH1: fnpic:110# ORPH1: fnpic:
173# ORPH1-NEXT: 20050: 00 00 00 00 nop111# ORPH1-NEXT: 20050: 00 00 00 00 nop
112
174# ORPH1: __LA25Thunk_foo1a:113# ORPH1: __LA25Thunk_foo1a:
175# ORPH1-NEXT: 20054: 3c 19 00 02 lui $25, 2114# ORPH1-NEXT: 20054: 3c 19 00 02 lui $25, 2
176# ORPH1-NEXT: 20058: 08 00 80 20 j 131200 <foo1a>115# ORPH1-NEXT: 20058: 08 00 80 20 j 131200 <foo1a>
177# ORPH1-NEXT: 2005c: 27 39 00 80 addiu $25, $25, 128116# ORPH1-NEXT: 2005c: 27 39 00 80 addiu $25, $25, 128
178# ORPH1-NEXT: 20060: 00 00 00 00 nop117# ORPH1-NEXT: 20060: 00 00 00 00 nop
118
179# ORPH1: __LA25Thunk_foo1b:119# ORPH1: __LA25Thunk_foo1b:
180# ORPH1-NEXT: 20064: 3c 19 00 02 lui $25, 2120# ORPH1-NEXT: 20064: 3c 19 00 02 lui $25, 2
181# ORPH1-NEXT: 20068: 08 00 80 21 j 131204 <foo1b>121# ORPH1-NEXT: 20068: 08 00 80 21 j 131204 <foo1b>
182# ORPH1-NEXT: 2006c: 27 39 00 84 addiu $25, $25, 132122# ORPH1-NEXT: 2006c: 27 39 00 84 addiu $25, $25, 132
183# ORPH1-NEXT: 20070: 00 00 00 00 nop123# ORPH1-NEXT: 20070: 00 00 00 00 nop
184# ORPH1-NEXT: 20074: ef ef ef ef <unknown>124
185# ORPH1-NEXT: 20078: ef ef ef ef <unknown>
186# ORPH1-NEXT: 2007c: ef ef ef ef <unknown>
187# ORPH1: foo1a:125# ORPH1: foo1a:
188# ORPH1-NEXT: 20080: 00 00 00 00 nop126# ORPH1-NEXT: 20080: 00 00 00 00 nop
127
189# ORPH1: foo1b:128# ORPH1: foo1b:
190# ORPH1-NEXT: 20084: 00 00 00 00 nop129# ORPH1-NEXT: 20084: 00 00 00 00 nop
130
191# ORPH1: __LA25Thunk_foo2:131# ORPH1: __LA25Thunk_foo2:
192# ORPH1-NEXT: 20088: 3c 19 00 02 lui $25, 2132# ORPH1-NEXT: 20088: 3c 19 00 02 lui $25, 2
193# ORPH1-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>133# ORPH1-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
194# ORPH1-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160134# ORPH1-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
195# ORPH1-NEXT: 20094: 00 00 00 00 nop135# ORPH1-NEXT: 20094: 00 00 00 00 nop
196# ORPH1-NEXT: 20098: ef ef ef ef <unknown>136
197# ORPH1-NEXT: 2009c: ef ef ef ef <unknown>
198# ORPH1: foo2:137# ORPH1: foo2:
199# ORPH1-NEXT: 200a0: 00 00 00 00 nop138# ORPH1-NEXT: 200a0: 00 00 00 00 nop
200139
...@@ -203,6 +142,7 @@ __start:...@@ -203,6 +142,7 @@ __start:
203# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script142# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script
204# RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe143# RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe
205# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s144# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s
145
206# ORPH2: Disassembly of section .out:146# ORPH2: Disassembly of section .out:
207# ORPH2-NEXT: __start:147# ORPH2-NEXT: __start:
208# ORPH2-NEXT: 20000: 0c 00 80 18 jal 131168 <__LA25Thunk_foo1a>148# ORPH2-NEXT: 20000: 0c 00 80 18 jal 131168 <__LA25Thunk_foo1a>
...@@ -217,39 +157,43 @@ __start:...@@ -217,39 +157,43 @@ __start:
217# ORPH2-NEXT: 20024: 00 00 00 00 nop157# ORPH2-NEXT: 20024: 00 00 00 00 nop
218# ORPH2-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>158# ORPH2-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
219# ORPH2-NEXT: 2002c: 00 00 00 00 nop159# ORPH2-NEXT: 2002c: 00 00 00 00 nop
160
220# ORPH2: __LA25Thunk_fpic:161# ORPH2: __LA25Thunk_fpic:
221# ORPH2-NEXT: 20030: 3c 19 00 02 lui $25, 2162# ORPH2-NEXT: 20030: 3c 19 00 02 lui $25, 2
222# ORPH2-NEXT: 20034: 08 00 80 10 j 131136 <fpic>163# ORPH2-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
223# ORPH2-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64164# ORPH2-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
224# ORPH2-NEXT: 2003c: 00 00 00 00 nop165# ORPH2-NEXT: 2003c: 00 00 00 00 nop
166
225# ORPH2: fpic:167# ORPH2: fpic:
226# ORPH2-NEXT: 20040: 00 00 00 00 nop168# ORPH2-NEXT: 20040: 00 00 00 00 nop
227# ORPH2-NEXT: 20044: ef ef ef ef <unknown>169
228# ORPH2-NEXT: 20048: ef ef ef ef <unknown>
229# ORPH2-NEXT: 2004c: ef ef ef ef <unknown>
230# ORPH2: fnpic:170# ORPH2: fnpic:
231# ORPH2-NEXT: 20050: 00 00 00 00 nop171# ORPH2-NEXT: 20050: 00 00 00 00 nop
232# ORPH2-NEXT: Disassembly of section .text:172# ORPH2-NEXT: Disassembly of section .text:
173
233# ORPH2-NEXT: __LA25Thunk_foo1a:174# ORPH2-NEXT: __LA25Thunk_foo1a:
234# ORPH2-NEXT: 20060: 3c 19 00 02 lui $25, 2175# ORPH2-NEXT: 20060: 3c 19 00 02 lui $25, 2
235# ORPH2-NEXT: 20064: 08 00 80 20 j 131200 <foo1a>176# ORPH2-NEXT: 20064: 08 00 80 20 j 131200 <foo1a>
236# ORPH2-NEXT: 20068: 27 39 00 80 addiu $25, $25, 128177# ORPH2-NEXT: 20068: 27 39 00 80 addiu $25, $25, 128
237# ORPH2-NEXT: 2006c: 00 00 00 00 nop178# ORPH2-NEXT: 2006c: 00 00 00 00 nop
179
238# ORPH2: __LA25Thunk_foo1b:180# ORPH2: __LA25Thunk_foo1b:
239# ORPH2-NEXT: 20070: 3c 19 00 02 lui $25, 2181# ORPH2-NEXT: 20070: 3c 19 00 02 lui $25, 2
240# ORPH2-NEXT: 20074: 08 00 80 21 j 131204 <foo1b>182# ORPH2-NEXT: 20074: 08 00 80 21 j 131204 <foo1b>
241# ORPH2-NEXT: 20078: 27 39 00 84 addiu $25, $25, 132183# ORPH2-NEXT: 20078: 27 39 00 84 addiu $25, $25, 132
242# ORPH2-NEXT: 2007c: 00 00 00 00 nop184# ORPH2-NEXT: 2007c: 00 00 00 00 nop
185
243# ORPH2: foo1a:186# ORPH2: foo1a:
244# ORPH2-NEXT: 20080: 00 00 00 00 nop187# ORPH2-NEXT: 20080: 00 00 00 00 nop
188
245# ORPH2: foo1b:189# ORPH2: foo1b:
246# ORPH2-NEXT: 20084: 00 00 00 00 nop190# ORPH2-NEXT: 20084: 00 00 00 00 nop
191
247# ORPH2: __LA25Thunk_foo2:192# ORPH2: __LA25Thunk_foo2:
248# ORPH2-NEXT: 20088: 3c 19 00 02 lui $25, 2193# ORPH2-NEXT: 20088: 3c 19 00 02 lui $25, 2
249# ORPH2-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>194# ORPH2-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
250# ORPH2-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160195# ORPH2-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
251# ORPH2-NEXT: 20094: 00 00 00 00 nop196# ORPH2-NEXT: 20094: 00 00 00 00 nop
252# ORPH2-NEXT: 20098: ef ef ef ef <unknown>197
253# ORPH2-NEXT: 2009c: ef ef ef ef <unknown>
254# ORPH2: foo2:198# ORPH2: foo2:
255# ORPH2-NEXT: 200a0: 00 00 00 00 nop199# ORPH2-NEXT: 200a0: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic.s+9-16
...@@ -51,8 +51,6 @@...@@ -51,8 +51,6 @@
51# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>51# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>
52# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 11252# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112
53# CHECK-NEXT: 20064: 00 00 00 00 nop53# CHECK-NEXT: 20064: 00 00 00 00 nop
54# CHECK-NEXT: 20068: ef ef ef ef <unknown>
55# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
5654
57# CHECK: foo2:55# CHECK: foo2:
58# CHECK-NEXT: 20070: 00 00 00 00 nop56# CHECK-NEXT: 20070: 00 00 00 00 nop
...@@ -62,15 +60,9 @@...@@ -62,15 +60,9 @@
62# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>60# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>
63# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 14461# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144
64# CHECK-NEXT: 20080: 00 00 00 00 nop62# CHECK-NEXT: 20080: 00 00 00 00 nop
65# CHECK-NEXT: 20084: ef ef ef ef <unknown>
66# CHECK-NEXT: 20088: ef ef ef ef <unknown>
67# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
6863
69# CHECK: fpic:64# CHECK: fpic:
70# CHECK-NEXT: 20090: 00 00 00 00 nop65# CHECK-NEXT: 20090: 00 00 00 00 nop
71# CHECK-NEXT: 20094: ef ef ef ef <unknown>
72# CHECK-NEXT: 20098: ef ef ef ef <unknown>
73# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
7466
75# CHECK: fnpic:67# CHECK: fnpic:
76# CHECK-NEXT: 200a0: 00 00 00 00 nop68# CHECK-NEXT: 200a0: 00 00 00 00 nop
...@@ -87,27 +79,28 @@...@@ -87,27 +79,28 @@
87# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>79# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
88# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 3280# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
89# REVERSE-NEXT: 2000c: 00 00 00 00 nop81# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82
90# REVERSE: __LA25Thunk_foo1b:83# REVERSE: __LA25Thunk_foo1b:
91# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 284# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
92# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>85# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
93# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 3686# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
94# REVERSE-NEXT: 2001c: 00 00 00 00 nop87# REVERSE-NEXT: 2001c: 00 00 00 00 nop
88
95# REVERSE: foo1a:89# REVERSE: foo1a:
96# REVERSE-NEXT: 20020: 00 00 00 00 nop90# REVERSE-NEXT: 20020: 00 00 00 00 nop
91
97# REVERSE: foo1b:92# REVERSE: foo1b:
98# REVERSE-NEXT: 20024: 00 00 00 00 nop93# REVERSE-NEXT: 20024: 00 00 00 00 nop
94
99# REVERSE: __LA25Thunk_foo2:95# REVERSE: __LA25Thunk_foo2:
100# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 296# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
101# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>97# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
102# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 6498# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
103# REVERSE-NEXT: 20034: 00 00 00 00 nop99# REVERSE-NEXT: 20034: 00 00 00 00 nop
104# REVERSE-NEXT: 20038: ef ef ef ef <unknown>100
105# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
106# REVERSE: foo2:101# REVERSE: foo2:
107# REVERSE-NEXT: 20040: 00 00 00 00 nop102# REVERSE-NEXT: 20040: 00 00 00 00 nop
108# REVERSE-NEXT: 20044: ef ef ef ef <unknown>103
109# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
110# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
111# REVERSE: __start:104# REVERSE: __start:
112# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>105# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
113# REVERSE-NEXT: 20054: 00 00 00 00 nop106# REVERSE-NEXT: 20054: 00 00 00 00 nop
...@@ -121,16 +114,16 @@...@@ -121,16 +114,16 @@
121# REVERSE-NEXT: 20074: 00 00 00 00 nop114# REVERSE-NEXT: 20074: 00 00 00 00 nop
122# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232 <fnpic>115# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232 <fnpic>
123# REVERSE-NEXT: 2007c: 00 00 00 00 nop116# REVERSE-NEXT: 2007c: 00 00 00 00 nop
117
124# REVERSE: __LA25Thunk_fpic:118# REVERSE: __LA25Thunk_fpic:
125# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2119# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2
126# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic>120# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic>
127# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144121# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144
128# REVERSE-NEXT: 2008c: 00 00 00 00 nop122# REVERSE-NEXT: 2008c: 00 00 00 00 nop
123
129# REVERSE: fpic:124# REVERSE: fpic:
130# REVERSE-NEXT: 20090: 00 00 00 00 nop125# REVERSE-NEXT: 20090: 00 00 00 00 nop
131# REVERSE-NEXT: 20094: ef ef ef ef <unknown>126
132# REVERSE-NEXT: 20098: ef ef ef ef <unknown>
133# REVERSE-NEXT: 2009c: ef ef ef ef <unknown>
134# REVERSE: fnpic:127# REVERSE: fnpic:
135# REVERSE-NEXT: 200a0: 00 00 00 00 nop128# REVERSE-NEXT: 200a0: 00 00 00 00 nop
136129
deps/lld/test/ELF/mips-sto-plt.s+2-2
...@@ -9,7 +9,7 @@...@@ -9,7 +9,7 @@
9# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s9# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
1010
11# CHECK: Symbol {11# CHECK: Symbol {
12# CHECK: Name: foo0@12# CHECK: Name: foo0
13# CHECK-NEXT: Value: 0x013# CHECK-NEXT: Value: 0x0
14# CHECK-NEXT: Size: 014# CHECK-NEXT: Size: 0
15# CHECK-NEXT: Binding: Global15# CHECK-NEXT: Binding: Global
...@@ -18,7 +18,7 @@...@@ -18,7 +18,7 @@
18# CHECK-NEXT: Section: Undefined18# CHECK-NEXT: Section: Undefined
19# CHECK-NEXT: }19# CHECK-NEXT: }
20# CHECK-NEXT: Symbol {20# CHECK-NEXT: Symbol {
21# CHECK-NEXT: Name: foo1@21# CHECK-NEXT: Name: foo1
22# CHECK-NEXT: Value: 0x[[FOO1:[0-9A-F]+]]22# CHECK-NEXT: Value: 0x[[FOO1:[0-9A-F]+]]
23# CHECK-NEXT: Size: 023# CHECK-NEXT: Size: 0
24# CHECK-NEXT: Binding: Global24# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/mips-tls-64.s+3-3
...@@ -28,9 +28,9 @@...@@ -28,9 +28,9 @@
28# DIS-NEXT: 30040 00000000 00000001 00000000 0000000028# DIS-NEXT: 30040 00000000 00000001 00000000 00000000
29# DIS-NEXT: 30050 00000000 00000001 ffffffff ffff800429# DIS-NEXT: 30050 00000000 00000001 ffffffff ffff8004
3030
31# DIS: 0000000000000000 l .tdata 00000000 loc31# DIS: 0000000000000000 l O .tdata 00000000 loc
32# DIS: 0000000000000004 g .tdata 00000000 bar32# DIS: 0000000000000004 g O .tdata 00000000 bar
33# DIS: 0000000000000000 g *UND* 00000000 foo33# DIS: 0000000000000000 g O *UND* 00000000 foo
3434
35# CHECK: Relocations [35# CHECK: Relocations [
36# CHECK-NEXT: Section (7) .rel.dyn {36# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-tls-hilo.s+1-1
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -2867220# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672
21# %lo(loc0 - .tdata - 0x7000) --^21# %lo(loc0 - .tdata - 0x7000) --^
2222
23# DIS: 00000000 l .tdata 00000000 loc023# DIS: 00000000 l O .tdata 00000000 loc0
2424
25# CHECK: Relocations [25# CHECK: Relocations [
26# CHECK-NEXT: ]26# CHECK-NEXT: ]
deps/lld/test/ELF/mips-tls-static-64.s+2-2
...@@ -11,8 +11,8 @@...@@ -11,8 +11,8 @@
11# CHECK-NEXT: 30010 ffff900411# CHECK-NEXT: 30010 ffff9004
12#12#
13# CHECK: SYMBOL TABLE:13# CHECK: SYMBOL TABLE:
14# CHECK: 0000000000020004 .text 00000000 __tls_get_addr14# CHECK: 0000000000020004 .text 00000000 __tls_get_addr
15# CHECK: 0000000000000000 g .tdata 00000000 tls115# CHECK: 0000000000000000 g O .tdata 00000000 tls1
1616
17 .text17 .text
18 .global __start18 .global __start
deps/lld/test/ELF/mips-tls-static.s+2-2
...@@ -13,8 +13,8 @@...@@ -13,8 +13,8 @@
13# CHECK-NEXT: 30020 ffff8000 00000001 0000000013# CHECK-NEXT: 30020 ffff8000 00000001 00000000
14#14#
15# CHECK: SYMBOL TABLE:15# CHECK: SYMBOL TABLE:
16# CHECK: 0002000c .text 00000000 __tls_get_addr16# CHECK: 0002000c .text 00000000 __tls_get_addr
17# CHECK: 00000000 g .tdata 00000000 tls117# CHECK: 00000000 g O .tdata 00000000 tls1
1818
19 .text19 .text
20 .global __start20 .global __start
deps/lld/test/ELF/mips-tls.s+3-3
...@@ -26,9 +26,9 @@...@@ -26,9 +26,9 @@
26# DIS-NEXT: 30020 00000000 00000000 00000001 0000000026# DIS-NEXT: 30020 00000000 00000000 00000001 00000000
27# DIS-NEXT: 30030 00000001 ffff800427# DIS-NEXT: 30030 00000001 ffff8004
2828
29# DIS: 00000000 l .tdata 00000000 loc29# DIS: 00000000 l O .tdata 00000000 loc
30# DIS: 00000004 g .tdata 00000000 bar30# DIS: 00000004 g O .tdata 00000000 bar
31# DIS: 00000000 g *UND* 00000000 foo31# DIS: 00000000 g O *UND* 00000000 foo
3232
33# CHECK: Relocations [33# CHECK: Relocations [
34# CHECK-NEXT: Section (7) .rel.dyn {34# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-traps.s created+22
...@@ -0,0 +1,22 @@
1# Check trap instruction encoding.
2
3# REQUIRES: mips
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 -o %t.o %s
6# RUN: ld.lld -r -o %t %t.o %t.o
7# RUN: llvm-objdump -d -r %t | FileCheck --check-prefix=EB %s
8
9# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux -mcpu=mips32r6 -o %t.o %s
10# RUN: ld.lld -r -o %t %t.o %t.o
11# RUN: llvm-objdump -d -r %t | FileCheck --check-prefix=EL %s
12
13# EB: 8: 04 17 00 01 sigrie 1
14# EL: 8: 01 00 17 04 sigrie 1
15
16 .text
17 lw $t9, %got(.data)($gp)
18 addiu $a0, $t9, %lo(.data)
19
20 .data
21data:
22 .word 0
deps/lld/test/ELF/msp430.s created+43
...@@ -0,0 +1,43 @@
1; REQUIRES: msp430
2; RUN: llvm-mc -filetype=obj -triple=msp430-elf -o %t1.o %s
3; RUN: echo -e '.global _start\n _start: nop' | llvm-mc -filetype=obj -triple=msp430-elf -o %t2.o -
4; RUN: ld.lld -o %t.exe --Tdata=0x2000 --Ttext=0x8000 --defsym=_byte=0x21 %t2.o %t1.o
5; RUN: llvm-objdump -s -d %t.exe | FileCheck %s
6
7;; Check handling of basic msp430 relocation types.
8
9 .text
10 .global foo
11foo:
12;; R_MSP430_10_PCREL
13 jmp _start
14
15; CHECK: Disassembly of section .text:
16; CHECK-NEXT: _start:
17; CHECK-NEXT: 8000: {{.*}} nop
18; CHECK: foo:
19; CHECK-NEXT: 8004: {{.*}} jmp $-4
20
21;; R_MSP430_16_BYTE
22 call #_start
23
24; CHECK: call #32768
25
26;; R_MSP430_16_PCREL_BYTE
27 mov #-1, _start
28
29; CHECK: 800a: {{.*}} mov #-1, -12
30
31 .data
32;; R_MSP430_8
33 .byte _byte
34;; R_MSP430_16
35 .word _start
36;; R_MSP430_32
37 .long _start
38
39; CHECK: Contents of section .data:
40; CHECK-NEXT: 2000 21008000 800000
41
42; RUN: od -x %t.exe | FileCheck -check-prefix=TRAP %s
43; TRAP: 4343 4343 4343 4343 4343 4343 4343 4343
deps/lld/test/ELF/no-discard-this_module.s created+41
...@@ -0,0 +1,41 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t
3// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
5
6.global _start
7_start:
8
9// This section and symbol is used by Linux kernel modules. Ensure it's not
10// accidentally discarded.
11.section .gnu.linkonce.this_module:
12__this_module:
13.byte 0x00
14
15// CHECK: Section {
16// CHECK: Index:
17// CHECK: Name: .gnu.linkonce.this_module
18// CHECK-NEXT: Type: SHT_PROGBITS
19// CHECK-NEXT: Flags [
20// CHECK-NEXT: ]
21// CHECK-NEXT: Address:
22// CHECK-NEXT: Offset:
23// CHECK-NEXT: Size:
24// CHECK-NEXT: Link:
25// CHECK-NEXT: Info:
26// CHECK-NEXT: AddressAlignment:
27// CHECK-NEXT: EntrySize:
28// CHECK-NEXT: SectionData (
29// CHECK-NEXT: 0000: 00 |.|
30// CHECK-NEXT: )
31// CHECK-NEXT: }
32
33// CHECK: Symbol {
34// CHECK: Name: __this_module
35// CHECK-NEXT: Value:
36// CHECK-NEXT: Size:
37// CHECK-NEXT: Binding: Local
38// CHECK-NEXT: Type: None
39// CHECK-NEXT: Other:
40// CHECK-NEXT: Section: .gnu.linkonce.this_module:
41// CHECK-NEXT: }
deps/lld/test/ELF/no-obj.s+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: rm -f %t.a
3// RUN: llvm-ar rcs %t.a %t.o4// RUN: llvm-ar rcs %t.a %t.o
4// RUN: not ld.lld -o /dev/null -u _start %t.a 2>&1 | FileCheck %s5// RUN: not ld.lld -o /dev/null -u _start %t.a 2>&1 | FileCheck %s
56
deps/lld/test/ELF/note-first-page.s created+12
...@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o --build-id=md5 --shared -o %t.so
4# RUN: llvm-readelf -S %t.so | FileCheck %s
5
6# Check .note.gnu.build-id is placed before other potentially large sections
7# (.dynsym .dynstr (and .rela.dyn in PIE)). This ensures the note information
8# available in core files because various core dumpers ensure the first page is
9# available.
10
11# CHECK: [ 1] .note.gnu.build-id
12# CHECK: [ 2] .dynsym
deps/lld/test/ELF/oformat-binary.s+1
...@@ -20,6 +20,7 @@...@@ -20,6 +20,7 @@
20# ERR: unknown --oformat value: foo20# ERR: unknown --oformat value: foo
2121
22# RUN: ld.lld -o /dev/null %t --oformat elf22# RUN: ld.lld -o /dev/null %t --oformat elf
23# RUN: ld.lld -o /dev/null %t --oformat elf-foo
2324
24.text25.text
25.align 426.align 4
deps/lld/test/ELF/pack-dyn-relocs-loop.s created+66
...@@ -0,0 +1,66 @@
1// REQUIRES: arm, aarch64
2
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-android %s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so --pack-dyn-relocs=android
5// RUN: llvm-readobj -s %t.so | FileCheck %s
6
7// This test is making sure the Android packed relocation support doesn't
8// cause an infinite loop due to the size of the section oscillating
9// (because the size of the section impacts the layout of the following
10// sections).
11
12// This test is very sensitive to the exact section sizes and offsets,
13// so check that they don't change.
14// CHECK: Name: .rela.dyn (33)
15// CHECK-NEXT: Type: SHT_ANDROID_RELA (0x60000002)
16// CHECK-NEXT: Flags [ (0x2)
17// CHECK-NEXT: SHF_ALLOC (0x2)
18// CHECK-NEXT: ]
19// CHECK-NEXT: Address: 0x210
20// CHECK-NEXT: Offset: 0x210
21// CHECK-NEXT: Size: 21
22
23// CHECK: Name: x (43)
24// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
25// CHECK-NEXT: Flags [ (0x2)
26// CHECK-NEXT: SHF_ALLOC (0x2)
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x225
29// CHECK-NEXT: Offset: 0x225
30// CHECK-NEXT: Size: 64980
31
32// CHECK: Name: barr (45)
33// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
34// CHECK-NEXT: Flags [ (0x2)
35// CHECK-NEXT: SHF_ALLOC (0x2)
36// CHECK-NEXT: ]
37// CHECK-NEXT: Address: 0xFFFA
38// CHECK-NEXT: Offset: 0xFFFA
39// CHECK-NEXT: Size: 0
40
41// CHECK: Name: foo (62)
42// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
43// CHECK-NEXT: Flags [ (0x3)
44// CHECK-NEXT: SHF_ALLOC (0x2)
45// CHECK-NEXT: SHF_WRITE (0x1)
46// CHECK-NEXT: ]
47// CHECK-NEXT: Address: 0x10004
48// CHECK-NEXT: Offset: 0x10004
49// CHECK-NEXT: Size: 12
50
51
52.data
53.long 0
54
55.section foo,"aw"
56foof:
57.long foof
58.long bar-53
59.long bar
60
61.section x,"a"
62.zero 64980
63
64.section barr,"a"
65.p2align 1
66bar:
deps/lld/test/ELF/pack-dyn-relocs-tls-aarch64.s created+34
...@@ -0,0 +1,34 @@
1// REQUIRES: aarch64
2
3// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
5// RUN: llvm-readobj -relocations %t.so | FileCheck %s
6
7// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
8// finalizeSections.
9
10 .global foo
11foo:
12 adrp x0, :tlsdesc:tlsvar1
13 ldr x1, [x0, :tlsdesc_lo12:tlsvar1]
14 add x0, x0, :tlsdesc_lo12:tlsvar1
15 .tlsdesccall tlsvar1
16
17// Also test an atypical IE access from a shared object to a local TLS symbol.
18
19 .global bar
20bar:
21 adrp x0, :gottprel:tlsvar2
22 ldr x0, [x0, #:gottprel_lo12:tlsvar2]
23
24 .section .tdata,"awT",@progbits
25 .space 0x1234
26tlsvar1:
27 .word 42
28tlsvar2:
29 .word 17
30
31// CHECK: Section ({{.+}}) .rela.dyn {
32// CHECK-NEXT: R_AARCH64_TLSDESC - 0x1234
33// CHECK-NEXT: R_AARCH64_TLS_TPREL64 - 0x1238
34// CHECK-NEXT: }
deps/lld/test/ELF/pack-dyn-relocs-tls-x86-64.s created+23
...@@ -0,0 +1,23 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
5// RUN: llvm-readobj -relocations %t.so | FileCheck %s
6
7// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
8// finalizeSections. This test uses an atypical IE access in a shared object to
9// access a local TLS symbol, because a more typical access would avoid the
10// bug.
11
12 .globl foo
13foo:
14 movq tlsvar@GOTTPOFF(%rip), %rcx
15
16 .section .tdata,"awT",@progbits
17 .space 0x1234
18tlsvar:
19 .word 42
20
21// CHECK: Section ({{.+}}) .rela.dyn {
22// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1234
23// CHECK-NEXT: }
deps/lld/test/ELF/plt-aarch64.s+46-36
...@@ -85,6 +85,8 @@...@@ -85,6 +85,8 @@
8585
86// foo@plt86// foo@plt
87// Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 6553687// Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 65536
88// DISASMDSO-EMPTY:
89// DISASMDSO-NEXT: foo@plt:
88// DISASMDSO-NEXT: 10030: 90 00 00 90 adrp x16, #6553690// DISASMDSO-NEXT: 10030: 90 00 00 90 adrp x16, #65536
89// 0x3018 & 0xFFF = 0x18 = 2491// 0x3018 & 0xFFF = 0x18 = 24
90// DISASMDSO-NEXT: 10034: 11 0e 40 f9 ldr x17, [x16, #24]92// DISASMDSO-NEXT: 10034: 11 0e 40 f9 ldr x17, [x16, #24]
...@@ -93,6 +95,8 @@...@@ -93,6 +95,8 @@
9395
94// bar@plt96// bar@plt
95// Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 6553697// Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 65536
98// DISASMDSO-EMPTY:
99// DISASMDSO-NEXT: bar@plt:
96// DISASMDSO-NEXT: 10040: 90 00 00 90 adrp x16, #65536100// DISASMDSO-NEXT: 10040: 90 00 00 90 adrp x16, #65536
97// 0x3020 & 0xFFF = 0x20 = 32101// 0x3020 & 0xFFF = 0x20 = 32
98// DISASMDSO-NEXT: 10044: 11 12 40 f9 ldr x17, [x16, #32]102// DISASMDSO-NEXT: 10044: 11 12 40 f9 ldr x17, [x16, #32]
...@@ -101,6 +105,8 @@...@@ -101,6 +105,8 @@
101105
102// weak@plt106// weak@plt
103// Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536107// Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536
108// DISASMDSO-EMPTY:
109// DISASMDSO-NEXT: weak@plt:
104// DISASMDSO-NEXT: 10050: 90 00 00 90 adrp x16, #65536110// DISASMDSO-NEXT: 10050: 90 00 00 90 adrp x16, #65536
105// 0x3028 & 0xFFF = 0x28 = 40111// 0x3028 & 0xFFF = 0x28 = 40
106// DISASMDSO-NEXT: 10054: 11 16 40 f9 ldr x17, [x16, #40]112// DISASMDSO-NEXT: 10054: 11 16 40 f9 ldr x17, [x16, #40]
...@@ -113,7 +119,7 @@...@@ -113,7 +119,7 @@
113// CHECKEXE-NEXT: SHF_ALLOC119// CHECKEXE-NEXT: SHF_ALLOC
114// CHECKEXE-NEXT: SHF_EXECINSTR120// CHECKEXE-NEXT: SHF_EXECINSTR
115// CHECKEXE-NEXT: ]121// CHECKEXE-NEXT: ]
116// CHECKEXE-NEXT: Address: 0x20010122// CHECKEXE-NEXT: Address: 0x210010
117// CHECKEXE-NEXT: Offset:123// CHECKEXE-NEXT: Offset:
118// CHECKEXE-NEXT: Size: 64124// CHECKEXE-NEXT: Size: 64
119// CHECKEXE-NEXT: Link:125// CHECKEXE-NEXT: Link:
...@@ -126,7 +132,7 @@...@@ -126,7 +132,7 @@
126// CHECKEXE-NEXT: SHF_ALLOC132// CHECKEXE-NEXT: SHF_ALLOC
127// CHECKEXE-NEXT: SHF_WRITE133// CHECKEXE-NEXT: SHF_WRITE
128// CHECKEXE-NEXT: ]134// CHECKEXE-NEXT: ]
129// CHECKEXE-NEXT: Address: 0x30000135// CHECKEXE-NEXT: Address: 0x220000
130// CHECKEXE-NEXT: Offset:136// CHECKEXE-NEXT: Offset:
131// CHECKEXE-NEXT: Size: 40137// CHECKEXE-NEXT: Size: 40
132// CHECKEXE-NEXT: Link:138// CHECKEXE-NEXT: Link:
...@@ -136,59 +142,63 @@...@@ -136,59 +142,63 @@
136// CHECKEXE: Relocations [142// CHECKEXE: Relocations [
137// CHECKEXE-NEXT: Section ({{.*}}) .rela.plt {143// CHECKEXE-NEXT: Section ({{.*}}) .rela.plt {
138144
139// &(.got.plt[3]) = 0x30000 + 3 * 8 = 0x30018145// &(.got.plt[3]) = 0x220000 + 3 * 8 = 0x220018
140// CHECKEXE-NEXT: 0x30018 R_AARCH64_JUMP_SLOT bar 0x0146// CHECKEXE-NEXT: 0x220018 R_AARCH64_JUMP_SLOT bar 0x0
141147
142// &(.got.plt[4]) = 0x30000 + 4 * 8 = 0x30020148// &(.got.plt[4]) = 0x220000 + 4 * 8 = 0x220020
143// CHECKEXE-NEXT: 0x30020 R_AARCH64_JUMP_SLOT weak 0x0149// CHECKEXE-NEXT: 0x220020 R_AARCH64_JUMP_SLOT weak 0x0
144// CHECKEXE-NEXT: }150// CHECKEXE-NEXT: }
145// CHECKEXE-NEXT: ]151// CHECKEXE-NEXT: ]
146152
147// DUMPEXE: Contents of section .got.plt:153// DUMPEXE: Contents of section .got.plt:
148// .got.plt[0..2] = 0 (reserved)154// .got.plt[0..2] = 0 (reserved)
149// .got.plt[3..4] = .plt = 0x40010155// .got.plt[3..4] = .plt = 0x40010
150// DUMPEXE-NEXT: 30000 00000000 00000000 00000000 00000000 ................156// DUMPEXE-NEXT: 220000 00000000 00000000 00000000 00000000
151// DUMPEXE-NEXT: 30010 00000000 00000000 10000200 00000000 ................157// DUMPEXE-NEXT: 220010 00000000 00000000 10002100 00000000
152// DUMPEXE-NEXT: 30020 10000200 00000000 ........158// DUMPEXE-NEXT: 220020 10002100 00000000
153159
154// DISASMEXE: _start:160// DISASMEXE: _start:
155// 0x2000c - 0x20000 = 0xc = 12161// 0x21000c - 0x210000 = 0xc = 12
156// DISASMEXE-NEXT: 20000: 03 00 00 14 b #12162// DISASMEXE-NEXT: 210000: 03 00 00 14 b #12
157// 0x20030 - 0x20004 = 0x2c = 44163// 0x210030 - 0x210004 = 0x2c = 44
158// DISASMEXE-NEXT: 20004: 0b 00 00 14 b #44164// DISASMEXE-NEXT: 210004: 0b 00 00 14 b #44
159// 0x20040 - 0x20008 = 0x38 = 56165// 0x210040 - 0x210008 = 0x38 = 56
160// DISASMEXE-NEXT: 20008: 0e 00 00 14 b #56166// DISASMEXE-NEXT: 210008: 0e 00 00 14 b #56
161167
162// DISASMEXE: foo:168// DISASMEXE: foo:
163// DISASMEXE-NEXT: 2000c: 1f 20 03 d5 nop169// DISASMEXE-NEXT: 21000c: 1f 20 03 d5 nop
164170
165// DISASMEXE: Disassembly of section .plt:171// DISASMEXE: Disassembly of section .plt:
166// DISASMEXE-NEXT: .plt:172// DISASMEXE-NEXT: .plt:
167// DISASMEXE-NEXT: 20010: f0 7b bf a9 stp x16, x30, [sp, #-16]!173// DISASMEXE-NEXT: 210010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
168// &(.got.plt[2]) = 0x300B0 + 2 * 8 = 0x300C0174// &(.got.plt[2]) = 0x2200B0 + 2 * 8 = 0x2200C0
169// Page(0x30010) - Page(0x20014) = 0x30000 - 0x20000 = 0x10000 = 65536175// Page(0x220010) - Page(0x210014) = 0x220000 - 0x210000 = 0x10000 = 65536
170// DISASMEXE-NEXT: 20014: 90 00 00 90 adrp x16, #65536176// DISASMEXE-NEXT: 210014: 90 00 00 90 adrp x16, #65536
171// 0x120c0 & 0xFFF = 0xC0 = 192177// 0x120c0 & 0xFFF = 0xC0 = 192
172// DISASMEXE-NEXT: 20018: 11 0a 40 f9 ldr x17, [x16, #16]178// DISASMEXE-NEXT: 210018: 11 0a 40 f9 ldr x17, [x16, #16]
173// DISASMEXE-NEXT: 2001c: 10 42 00 91 add x16, x16, #16179// DISASMEXE-NEXT: 21001c: 10 42 00 91 add x16, x16, #16
174// DISASMEXE-NEXT: 20020: 20 02 1f d6 br x17180// DISASMEXE-NEXT: 210020: 20 02 1f d6 br x17
175// DISASMEXE-NEXT: 20024: 1f 20 03 d5 nop181// DISASMEXE-NEXT: 210024: 1f 20 03 d5 nop
176// DISASMEXE-NEXT: 20028: 1f 20 03 d5 nop182// DISASMEXE-NEXT: 210028: 1f 20 03 d5 nop
177// DISASMEXE-NEXT: 2002c: 1f 20 03 d5 nop183// DISASMEXE-NEXT: 21002c: 1f 20 03 d5 nop
178184
179// bar@plt185// bar@plt
180// Page(0x40018) - Page(0x20030) = 0x30000 - 0x20000 = 0x10000 = 65536186// Page(0x40018) - Page(0x210030) = 0x220000 - 0x210000 = 0x10000 = 65536
181// DISASMEXE-NEXT: 20030: 90 00 00 90 adrp x16, #65536187// DISASMEXE-EMPTY:
182// DISASMEXE-NEXT: 20034: 11 0e 40 f9 ldr x17, [x16, #24]188// DISASMEXE-NEXT: bar@plt:
183// DISASMEXE-NEXT: 20038: 10 62 00 91 add x16, x16, #24189// DISASMEXE-NEXT: 210030: 90 00 00 90 adrp x16, #65536
184// DISASMEXE-NEXT: 2003c: 20 02 1f d6 br x17190// DISASMEXE-NEXT: 210034: 11 0e 40 f9 ldr x17, [x16, #24]
191// DISASMEXE-NEXT: 210038: 10 62 00 91 add x16, x16, #24
192// DISASMEXE-NEXT: 21003c: 20 02 1f d6 br x17
185193
186// weak@plt194// weak@plt
187// Page(0x40020) - Page(0x20040) = 0x30000 - 0x20000 = 0x10000 = 65536195// Page(0x40020) - Page(0x210040) = 0x220000 - 0x210000 = 0x10000 = 65536
188// DISASMEXE-NEXT: 20040: 90 00 00 90 adrp x16, #65536196// DISASMEXE-EMPTY:
189// DISASMEXE-NEXT: 20044: 11 12 40 f9 ldr x17, [x16, #32]197// DISASMEXE-NEXT: weak@plt:
190// DISASMEXE-NEXT: 20048: 10 82 00 91 add x16, x16, #32198// DISASMEXE-NEXT: 210040: 90 00 00 90 adrp x16, #65536
191// DISASMEXE-NEXT: 2004c: 20 02 1f d6 br x17199// DISASMEXE-NEXT: 210044: 11 12 40 f9 ldr x17, [x16, #32]
200// DISASMEXE-NEXT: 210048: 10 82 00 91 add x16, x16, #32
201// DISASMEXE-NEXT: 21004c: 20 02 1f d6 br x17
192202
193.global _start,foo,bar203.global _start,foo,bar
194.weak weak204.weak weak
deps/lld/test/ELF/plt-i686.s+36-32
...@@ -17,7 +17,7 @@...@@ -17,7 +17,7 @@
17// CHECK-NEXT: SHF_ALLOC17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: SHF_EXECINSTR18// CHECK-NEXT: SHF_EXECINSTR
19// CHECK-NEXT: ]19// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x1102020// CHECK-NEXT: Address: 0x401020
21// CHECK-NEXT: Offset:21// CHECK-NEXT: Offset:
22// CHECK-NEXT: Size: 4822// CHECK-NEXT: Size: 48
23// CHECK-NEXT: Link: 023// CHECK-NEXT: Link: 0
...@@ -30,7 +30,7 @@...@@ -30,7 +30,7 @@
30// CHECK-NEXT: SHF_ALLOC30// CHECK-NEXT: SHF_ALLOC
31// CHECK-NEXT: SHF_WRITE31// CHECK-NEXT: SHF_WRITE
32// CHECK-NEXT: ]32// CHECK-NEXT: ]
33// CHECK-NEXT: Address: 0x1200033// CHECK-NEXT: Address: 0x402000
34// CHECK-NEXT: Offset: 0x200034// CHECK-NEXT: Offset: 0x2000
35// CHECK-NEXT: Size: 2035// CHECK-NEXT: Size: 20
36// CHECK-NEXT: Link: 036// CHECK-NEXT: Link: 0
...@@ -42,8 +42,8 @@...@@ -42,8 +42,8 @@
42// 0x12000 + got.plt.reserved(12) + 4 = 0x1201042// 0x12000 + got.plt.reserved(12) + 4 = 0x12010
43// CHECK: Relocations [43// CHECK: Relocations [
44// CHECK-NEXT: Section ({{.*}}) .rel.plt {44// CHECK-NEXT: Section ({{.*}}) .rel.plt {
45// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar 0x045// CHECK-NEXT: 0x40200C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed 0x046// CHECK-NEXT: 0x402010 R_386_JUMP_SLOT zed 0x0
47// CHECK-NEXT: }47// CHECK-NEXT: }
48// CHECK-NEXT: ]48// CHECK-NEXT: ]
4949
...@@ -51,40 +51,44 @@...@@ -51,40 +51,44 @@
51// values:51// values:
5252
53// 16 is the size of PLT[0]53// 16 is the size of PLT[0]
54// (0x11010 + 16) - (0x11000 + 1) - 4 = 2754// (0x401010 + 16) - (0x401000 + 1) - 4 = 27
55// (0x11010 + 16) - (0x11005 + 1) - 4 = 2255// (0x401010 + 16) - (0x401005 + 1) - 4 = 22
56// (0x11020 + 16) - (0x1100a + 1) - 4 = 3356// (0x401020 + 16) - (0x40100a + 1) - 4 = 33
5757
58// DISASM: local:58// DISASM: local:
59// DISASM-NEXT: 11000: {{.*}}59// DISASM-NEXT: 401000: {{.*}}
60// DISASM-NEXT: 11002: {{.*}}60// DISASM-NEXT: 401002: {{.*}}
61// DISASM: _start:61// DISASM: _start:
62// 0x11013 + 5 - 24 = 0x1100062// 0x401013 + 5 - 24 = 0x401000
63// DISASM-NEXT: 11004: e9 27 00 00 00 jmp 3963// DISASM-NEXT: 401004: e9 27 00 00 00 jmp 39
64// DISASM-NEXT: 11009: e9 22 00 00 00 jmp 3464// DISASM-NEXT: 401009: e9 22 00 00 00 jmp 34
65// DISASM-NEXT: 1100e: e9 2d 00 00 00 jmp 4565// DISASM-NEXT: 40100e: e9 2d 00 00 00 jmp 45
66// DISASM-NEXT: 11013: e9 e8 ff ff ff jmp -2466// DISASM-NEXT: 401013: e9 e8 ff ff ff jmp -24
6767
68// 0x11010 - 0x1102b - 5 = -3268// 0x401010 - 0x40102b - 5 = -32
69// 0x11010 - 0x1103b - 5 = -4869// 0x401010 - 0x40103b - 5 = -48
70// 77828 = 0x13004 = .got.plt (0x13000) + 470// 4202500 = 0x402004 = .got.plt (0x402000) + 4
71// 77832 = 0x13008 = .got.plt (0x13000) + 871// 4202504 = 0x402008 = .got.plt (0x402000) + 8
72// 77836 = 0x1300C = .got.plt (0x13000) + got.plt.reserved(12)72// 4202508 = 0x40200C = .got.plt (0x402000) + got.plt.reserved(12)
73// 77840 = 0x13010 = .got.plt (0x13000) + got.plt.reserved(12) + 473// 4202512 = 0x402010 = .got.plt (0x402000) + got.plt.reserved(12) + 4
74// DISASM: Disassembly of section .plt:74// DISASM: Disassembly of section .plt:
75// DISASM-NEXT: .plt:75// DISASM-NEXT: .plt:
76// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 7373276// DISASM-NEXT: 401020: ff 35 04 20 40 00 pushl 4202500
77// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *7373677// DISASM-NEXT: 401026: ff 25 08 20 40 00 jmpl *4202504
78// DISASM-NEXT: 1102c: 90 nop78// DISASM-NEXT: 40102c: 90 nop
79// DISASM-NEXT: 1102d: 90 nop79// DISASM-NEXT: 40102d: 90 nop
80// DISASM-NEXT: 1102e: 90 nop80// DISASM-NEXT: 40102e: 90 nop
81// DISASM-NEXT: 1102f: 90 nop81// DISASM-NEXT: 40102f: 90 nop
82// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *7374082// DISASM-EMPTY:
83// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $083// DISASM-NEXT: bar@plt:
84// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>84// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
85// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *7374485// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
86// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $886// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.plt>
87// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>87// DISASM-EMPTY:
88// DISASM-NEXT: zed@plt:
89// DISASM-NEXT: 401040: ff 25 10 20 40 00 jmpl *4202512
90// DISASM-NEXT: 401046: 68 08 00 00 00 pushl $8
91// DISASM-NEXT: 40104b: e9 d0 ff ff ff jmp -48 <.plt>
8892
89// CHECKSHARED: Name: .plt93// CHECKSHARED: Name: .plt
90// CHECKSHARED-NEXT: Type: SHT_PROGBITS94// CHECKSHARED-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/plt.s+10
...@@ -73,12 +73,18 @@...@@ -73,12 +73,18 @@
73// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)73// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
74// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)74// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
75// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)75// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
76// DISASM-EMPTY:
77// DISASM-NEXT: bar@plt:
76// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)78// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
77// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $079// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
78// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>80// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
81// DISASM-EMPTY:
82// DISASM-NEXT: zed@plt:
79// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)83// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
80// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $184// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
81// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>85// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
86// DISASM-EMPTY:
87// DISASM-NEXT: _start@plt:
82// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)88// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
83// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $289// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2
84// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <.plt>90// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <.plt>
...@@ -102,9 +108,13 @@...@@ -102,9 +108,13 @@
102// DISASM2-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)108// DISASM2-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
103// DISASM2-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)109// DISASM2-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
104// DISASM2-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)110// DISASM2-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
111// DISASM2-EMPTY:
112// DISASM2-NEXT: bar@plt:
105// DISASM2-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)113// DISASM2-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
106// DISASM2-NEXT: 201036: 68 00 00 00 00 pushq $0114// DISASM2-NEXT: 201036: 68 00 00 00 00 pushq $0
107// DISASM2-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>115// DISASM2-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
116// DISASM2-EMPTY:
117// DISASM2-NEXT: zed@plt:
108// DISASM2-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)118// DISASM2-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
109// DISASM2-NEXT: 201046: 68 01 00 00 00 pushq $1119// DISASM2-NEXT: 201046: 68 01 00 00 00 pushq $1
110// DISASM2-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>120// DISASM2-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
deps/lld/test/ELF/ppc-relocs.s+14-3
...@@ -55,6 +55,17 @@ mystr:...@@ -55,6 +55,17 @@ mystr:
55# CHECK: .FR_PPC_REL24:55# CHECK: .FR_PPC_REL24:
56# CHECK: 1101c: 48 00 00 04 b .+456# CHECK: 1101c: 48 00 00 04 b .+4
5757
58.section .R_PPC_REL14,"ax",@progbits
59.globl .FR_PPC_REL14
60.FR_PPC_REL14:
61 beq .Lfooy
62.section .R_PPC_REL14_2,"ax",@progbits
63.Lfooy:
64
65# CHECK: Disassembly of section .R_PPC_REL14:
66# CHECK: .FR_PPC_REL14:
67# CHECK: 11020: {{.*}} bt 2, .+4
68
58.section .R_PPC_REL32,"ax",@progbits69.section .R_PPC_REL32,"ax",@progbits
59.globl .FR_PPC_REL3270.globl .FR_PPC_REL32
60.FR_PPC_REL32:71.FR_PPC_REL32:
...@@ -64,7 +75,7 @@ mystr:...@@ -64,7 +75,7 @@ mystr:
6475
65# CHECK: Disassembly of section .R_PPC_REL32:76# CHECK: Disassembly of section .R_PPC_REL32:
66# CHECK: .FR_PPC_REL32:77# CHECK: .FR_PPC_REL32:
67# CHECK: 11020: 00 00 00 0478# CHECK: 11024: 00 00 00 04
6879
69.section .R_PPC_ADDR32,"ax",@progbits80.section .R_PPC_ADDR32,"ax",@progbits
70.globl .FR_PPC_ADDR3281.globl .FR_PPC_ADDR32
...@@ -75,7 +86,7 @@ mystr:...@@ -75,7 +86,7 @@ mystr:
7586
76# CHECK: Disassembly of section .R_PPC_ADDR32:87# CHECK: Disassembly of section .R_PPC_ADDR32:
77# CHECK: .FR_PPC_ADDR32:88# CHECK: .FR_PPC_ADDR32:
78# CHECK: 11024: 00 01 10 2889# CHECK: 11028: 00 01 10 2c
7990
80.align 291.align 2
81.section .R_PPC_PLTREL24,"ax",@progbits92.section .R_PPC_PLTREL24,"ax",@progbits
...@@ -87,4 +98,4 @@ mystr:...@@ -87,4 +98,4 @@ mystr:
8798
88# CHECK: Disassembly of section .R_PPC_PLTREL24:99# CHECK: Disassembly of section .R_PPC_PLTREL24:
89# CHECK: .R_PPC_PLTREL24:100# CHECK: .R_PPC_PLTREL24:
90# CHECK: 11028: 48 00 00 04 b .+4101# CHECK: 1102c: 48 00 00 04 b .+4
deps/lld/test/ELF/ppc64-bsymbolic-toc-restore.s created+68
...@@ -0,0 +1,68 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-bsymbolic-local-def.s -o %t2.o
5# RUN: ld.lld -Bsymbolic -shared %t1.o %t2.o -o %t
6# RUN: llvm-objdump -d -r %t | FileCheck %s
7# RUN: not ld.lld -shared %t1.o %t2.o -o %t 2>&1 | FileCheck --check-prefix=FAIL %s
8
9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
10# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-bsymbolic-local-def.s -o %t2.o
11# RUN: ld.lld -Bsymbolic -shared %t1.o %t2.o -o %t
12# RUN: llvm-objdump -d -r %t | FileCheck %s
13# RUN: not ld.lld -shared %t1.o %t2.o -o %t 2>&1 | FileCheck --check-prefix=FAIL %s
14
15# FAIL: call lacks nop, can't restore toc
16
17# Test to document the toc-restore behavior with -Bsymbolic option. Since
18# -Bsymbolic causes the call to bind to the internal defintion we know the
19# caller and callee share the same TOC base. This means branching to the
20# local entry point of the callee, and no need for a nop to follow the call
21# (since there is no need to restore the TOC-pointer after the call).
22
23 .abiversion 2
24 .section ".text"
25
26 .p2align 2
27 .global caller
28 .type caller, @function
29caller:
30.Lcaller_gep:
31 addis 2, 12, .TOC.-.Lcaller_gep@ha
32 addi 2, 2, .TOC.-.Lcaller_gep@l
33.Lcaller_lep:
34 .localentry caller, .-caller
35 mflr 0
36 std 0, -16(1)
37 stdu 1, -32(1)
38 bl def
39 mr 31, 3
40 bl not_defined
41 nop
42 add 3, 3, 31
43 addi 1, 1, 32
44 ld 0, -16(1)
45 mtlr 0
46 blr
47
48# Note that the bl .+44 is a call to def's local entry, jumping past the first 2
49# instructions. Branching to the global entry would corrupt the TOC pointer
50# since the global entry requires that %r12 hold the address of the function
51# being called.
52
53# CHECK-LABEL: caller
54# CHECK: bl .+44
55# CHECK-NEXT: mr 31, 3
56# CHECK-NEXT: bl .+67108816
57# CHECK-NEXT: ld 2, 24(1)
58# CHECK-NEXT: add 3, 3, 31
59# CHECK-NEXT: addi 1, 1, 32
60# CHECK-NEXT: ld 0, -16(1)
61# CHECK-NEXT: mtlr 0
62# CHECK-NEXT: blr
63# CHECK-EMPTY:
64# CHECK-NEXT: def:
65# CHECK-NEXT: addis 2, 12, 2
66# CHECK-NEXT: addi 2, 2, -32636
67# CHECK-NEXT: li 3, 55
68# CHECK-NEXT: blr
deps/lld/test/ELF/ppc64-call-reach.s created+94
...@@ -0,0 +1,94 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
5# RUN: %t.o -o %t
6# RUN: llvm-objdump -d %t | FileCheck %s
7# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
8# RUN: %t.o -o %t
9# RUN: llvm-objdump -d %t | FileCheck %s
10# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
11# RUN: %t.o -o %t
12# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s
13# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
14# RUN: %t.o -o %t
15# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s
16# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
17# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
18# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
19
20# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
21# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
22# RUN: %t.o -o %t
23# RUN: llvm-objdump -d %t | FileCheck %s
24# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
25# RUN: %t.o -o %t
26# RUN: llvm-objdump -d %t | FileCheck %s
27# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
28# RUN: %t.o -o %t
29# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s
30# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
31# RUN: %t.o -o %t
32# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s
33# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
34# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
35# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
36
37# MISSALIGNED: ld.lld: error: {{.*}}.o:(.text+0x14): improper alignment for relocation R_PPC64_REL24: 0x19 is not aligned to 4 bytes
38# MISSALIGNED: ld.lld: error: {{.*}}.o:(.text+0x24): improper alignment for relocation R_PPC64_REL24: 0xB is not aligned to 4 bytes
39
40 .global test
41 .p2align 4
42 .type test,@function
43test:
44.Lgep:
45 addis 2, 12, .TOC.-.Lgep@ha
46 addi 2, 2, .TOC.-.Lgep@l
47.Llep:
48 .localentry test, .Llep-.Lgep
49 mflr 0
50 std 0, 16(1)
51 stdu 1, 32(1)
52 bl callee
53 addi 1, 1, 32
54 ld 0, 16(1)
55 mtlr 0
56 b tail_callee
57
58# Check that we are branching to the definitions, and not range-extending
59# thunks.
60# CHECK-LABEL: test
61# CHECK: 10010014: {{.*}} bl .+33554428
62# CHECK: 10010024: {{.*}} b .+33554428
63
64# NEGOFFSET-LABEL: test
65# NEGOFFSET: 10010014: {{.*}} bl .+33554432
66# NEGOFFSET: 10010024: {{.*}} b .+33554432
67
68# .branch_lt[0]
69# THUNK-LABEL: __long_branch_callee:
70# THUNK-NEXT: 10010000: {{.*}} addis 12, 2, -1
71# THUNK-NEXT: ld 12, -32768(12)
72# THUNK-NEXT: mtctr 12
73# THUNK-NEXT: bctr
74
75# .branch_lt[1]
76# THUNK-LABEL: __long_branch_tail_callee:
77# THUNK-NEXT: 10010010: {{.*}} addis 12, 2, -1
78# THUNK-NEXT: ld 12, -32760(12)
79# THUNK-NEXT: mtctr 12
80# THUNK-NEXT: bctr
81
82# Each call now branches to a thunk, and although it is printed as positive
83# the offset is interpreted as a signed 26 bit value so 67108812 is actually
84# -52.
85# THUNK-LABEL: test:
86# THUNK: 10010034: {{.*}} bl .+67108812
87# THUNK: 10010044: {{.*}} b .+67108812
88
89# The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768.
90# Name Type Address Off Size
91# BRANCHLT: .branch_lt PROGBITS 0000000010020000 020000 000010
92# BRANCHLT: .got PROGBITS 0000000010030000 030000 000008
93# BRANCHLT-NOT: .plt
94
deps/lld/test/ELF/ppc64-dq.s created+32
...@@ -0,0 +1,32 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-objdump -d %t | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
8# RUN: ld.lld %t.o -o %t
9# RUN: llvm-objdump -d %t | FileCheck %s
10
11 .global test
12 .p2align 4
13 .type test,@function
14test:
15.Lgep:
16 addis 2, 12, .TOC.-.Lgep@ha
17 addi 2, 2, .TOC.-.Lgep@l
18.Llep:
19 .localentry test, .Llep-.Lgep
20 addis 3, 2, qword@toc@ha
21 lxv 3, qword@toc@l(3)
22 addis 3, 2, qword@toc@ha
23 stxv 3, qword@toc@l(3)
24 blr
25
26 .comm qword, 16, 16
27
28# Verify that we don't overwrite any of the extended opcode bits on a DQ form
29# instruction.
30# CHECK-LABEL: test
31# CHECK: lxv 3, -32768(3)
32# CHECK: stxv 3, -32768(3)
deps/lld/test/ELF/ppc64-dtprel.s+4-4
...@@ -2,15 +2,15 @@...@@ -2,15 +2,15 @@
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so4// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s7// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %s8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %s
99
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
11// RUN: ld.lld -shared %t.o -o %t.so11// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
14// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s14// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisBE %s15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisBE %s
1616
deps/lld/test/ELF/ppc64-entry-point.s created+49
...@@ -0,0 +1,49 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-objdump -D %t2 | FileCheck %s
6# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %s
7
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
9# RUN: ld.lld %t -o %t2
10# RUN: llvm-objdump -D %t2 | FileCheck %s
11# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
12
13.text
14.abiversion 2
15.globl _start
16.p2align 4
17.type _start,@function
18
19_start:
20.Lfunc_begin0:
21.Lfunc_gep0:
22 lis 4, .Lfunc_gep0@ha
23 addi 4, 4, .Lfunc_gep0@l
24 # now r4 should contain the address of _start
25
26 lis 5, .TOC.-.Lfunc_gep0@ha
27 addi 5, 5, .TOC.-.Lfunc_gep0@l
28 # now r5 should contain the offset s.t. r4 + r5 = TOC base
29
30 # exit 55
31 li 0, 1
32 li 3, 55
33 sc
34.Lfunc_end0:
35 .size _start, .Lfunc_end0-.Lfunc_begin0
36
37// CHECK: 10010000: {{.*}} lis 4, 4097
38// CHECK-NEXT: 10010004: {{.*}} addi 4, 4, 0
39// CHECK-NEXT: 10010008: {{.*}} lis 5, 2
40// CHECK-NEXT: 1001000c: {{.*}} addi 5, 5, -32768
41
42// CHECK-LE: Disassembly of section .got:
43// CHECK-LE-NEXT: .got:
44// CHECK-LE-NEXT: 10020000: 00 80 02 10
45
46// CHECK-BE: Disassembly of section .got:
47// CHECK-BE-NEXT: .got:
48// CHECK-BE-NEXT: 10020000: 00 00 00 00 {{.*}}
49// CHECK-BE-NEXT: 10020004: 10 02 80 00 {{.*}}
deps/lld/test/ELF/ppc64-error-missaligned-dq.s created+26
...@@ -0,0 +1,26 @@
1# REQUIRES: ppc
2#
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
5
6# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
7# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
8
9# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 16 bytes
10
11 .global test
12 .p2align 4
13 .type test,@function
14test:
15.Lgep:
16 addis 2, 12, .TOC.-.Lgep@ha
17 addi 2, 2, .TOC.-.Lgep@l
18.Llep:
19 .localentry test, .Llep-.Lgep
20 addis 3, 2, qword@toc@ha
21 lxv 3, qword@toc@l(3)
22 blr
23
24 .comm pad, 1, 1
25 .comm qword, 16, 1
26
deps/lld/test/ELF/ppc64-error-missaligned-ds.s created+26
...@@ -0,0 +1,26 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
5
6# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
7# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
8
9# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 4 bytes
10
11 .global test
12 .p2align 4
13 .type test,@function
14test:
15.Lgep:
16 addis 2, 12, .TOC.-.Lgep@ha
17 addi 2, 2, .TOC.-.Lgep@l
18.Llep:
19 .localentry test, .Llep-.Lgep
20 addis 3, 2, word@toc@ha
21 lwa 3, word@toc@l(3)
22 blr
23
24 .comm pad, 1, 1
25 .comm word, 4, 1
26
deps/lld/test/ELF/ppc64-func-entry-points.s+1-1
...@@ -75,6 +75,6 @@ glob:...@@ -75,6 +75,6 @@ glob:
75// CHECK: foo_external_diff:75// CHECK: foo_external_diff:
76// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 276// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2
77// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 3264077// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640
78// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 078// CHECK-NEXT: 10010088: {{.*}} nop
79// CHECK: foo_external_same:79// CHECK: foo_external_same:
80// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 380// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3
deps/lld/test/ELF/ppc64-gd-to-ie.s+4-4
...@@ -5,16 +5,16 @@...@@ -5,16 +5,16 @@
5# RUN: ld.lld -shared %t2.o -o %t3.so5# RUN: ld.lld -shared %t2.o -o %t3.so
6# RUN: ld.lld %t.o %t3.so -o %t6# RUN: ld.lld %t.o %t3.so -o %t
7# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s7# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
8# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s8# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
9# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s9# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1010
11# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o11# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
12# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o12# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
13# RUN: ld.lld -shared %t2.o -o %t3.so13# RUN: ld.lld -shared %t2.o -o %t3.so
14# RUN: ld.lld %t.o %t3.so -o %t14# RUN: ld.lld %t.o %t3.so -o %t
15# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s15# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
16# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s16# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
17# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s17# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1818
19 .text19 .text
20 .abiversion 220 .abiversion 2
deps/lld/test/ELF/ppc64-general-dynamic-tls.s+6-6
...@@ -2,17 +2,17 @@...@@ -2,17 +2,17 @@
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so4// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
99
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
11// RUN: ld.lld -shared %t.o -o %t.so11// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
1616
17 .text17 .text
18 .abiversion 218 .abiversion 2
deps/lld/test/ELF/ppc64-got-indirect.s+2-2
...@@ -83,8 +83,8 @@ glob:...@@ -83,8 +83,8 @@ glob:
83# CHECK: _start:83# CHECK: _start:
84# CHECK-NEXT: 10010000: {{.*}} addis 2, 12, 384# CHECK-NEXT: 10010000: {{.*}} addis 2, 12, 3
85# CHECK-NEXT: 10010004: {{.*}} addi 2, 2, -3276885# CHECK-NEXT: 10010004: {{.*}} addi 2, 2, -32768
86# CHECK-NEXT: 10010008: {{.*}} addis 3, 2, 086# CHECK-NEXT: 10010008: {{.*}} nop
87# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(3)87# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(2)
88# CHECK: 1001001c: {{.*}} lwa 3, 0(3)88# CHECK: 1001001c: {{.*}} lwa 3, 0(3)
8989
90# CHECK-LE: Disassembly of section .data:90# CHECK-LE: Disassembly of section .data:
deps/lld/test/ELF/ppc64-got-off.s created+67
...@@ -0,0 +1,67 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared --no-toc-optimize %t.o -o %t
5# RUN: llvm-objdump -d %t | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
8# RUN: ld.lld -shared --no-toc-optimize %t.o -o %t
9# RUN: llvm-objdump -d %t | FileCheck %s
10
11# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
12# RUN: ld.lld -shared %t.o -o %t
13# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
14
15# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
16# RUN: ld.lld -shared %t.o -o %t
17# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
18
19 .abiversion 2
20 .section ".text"
21
22 .p2align 2
23 .global func
24 .type func, @function
25func:
26.Lfunc_gep:
27 addis 2, 12, .TOC.-.Lfunc_gep@ha
28 addi 2, 2, .TOC.-.Lfunc_gep@l
29.Lfunc_lep:
30 .localentry func, .-func
31 addis 3, 2, a@got@ha
32 ld 3, a@got@l(3)
33 ld 4, a@got(2)
34 lis 5, a@got@h
35 ori 5, 5, a@got@l
36 li 6, 0
37 ori 6, 6, a@got
38 blr
39
40# CHECK-LABEL: func
41# CHECK: addis 3, 2, 0
42# CHECK-NEXT: ld 3, -32760(3)
43# CHECK-NEXT: ld 4, -32760(2)
44# CHECK-NEXT: lis 5, -1
45# CHECK-NEXT: ori 5, 5, 32776
46# CHECK-NEXT: li 6, 0
47# CHECK-NEXT: ori 6, 6, 32776
48
49# OPT-LABEL: func
50# OPT: nop
51# OPT-NEXT: ld 3, -32760(2)
52# OPT-NEXT: ld 4, -32760(2)
53# OPT-NEXT: lis 5, -1
54# OPT-NEXT: ori 5, 5, 32776
55# OPT-NEXT: li 6, 0
56# OPT-NEXT: ori 6, 6, 32776
57
58# Since the got entry for a is .got[1] and the TOC base points to
59# .got + 0x8000, the offset for a@got is -0x7FF8 --> -32760
60
61 .section ".data"
62 .global a
63 .type a, @object
64 .size a, 4
65 .p2align 2
66a:
67 .long 0x1000
deps/lld/test/ELF/ppc64-initial-exec-tls.s+6-6
...@@ -4,19 +4,19 @@...@@ -4,19 +4,19 @@
4// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o4// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t6// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
7// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s7// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
8// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s8// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
9// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s9// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
10// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s10// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
1111
12// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o12// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
13// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o13// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
14// RUN: ld.lld -shared %t2.o -o %t2.so14// RUN: ld.lld -shared %t2.o -o %t2.so
15// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t15// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
16// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s16// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
17// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s17// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
18// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s18// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
19// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s19// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
2020
21 .text21 .text
22 .abiversion 222 .abiversion 2
deps/lld/test/ELF/ppc64-local-dynamic.s+6-6
...@@ -2,17 +2,17 @@...@@ -2,17 +2,17 @@
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so4// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
99
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
11// RUN: ld.lld -shared %t.o -o %t.so11// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
1616
17 .text17 .text
18 .abiversion 218 .abiversion 2
deps/lld/test/ELF/ppc64-local-exec-tls.s+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1// REQUIRES: ppc1// REQUIRES: ppc
2// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s5// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
66
7 .text7 .text
8 .abiversion 28 .abiversion 2
deps/lld/test/ELF/ppc64-long-branch.s created+121
...@@ -0,0 +1,121 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -o %t3.so
6# RUN: ld.lld --no-toc-optimize %t.o %t3.so -o %t
7# RUN: llvm-objdump -d -start-address=0x10010000 -stop-address=0x10010018 %t | FileCheck %s -check-prefix=CALLEE_DUMP
8# RUN: llvm-objdump -d -start-address=0x12010020 -stop-address=0x12010084 %t | FileCheck %s -check-prefix=CALLER_DUMP
9# RUN: llvm-objdump -D -start-address=0x12020008 -stop-address=0x12020010 %t | FileCheck %s -check-prefix=BRANCH_LT_LE
10# RUN: llvm-readelf --sections %t | FileCheck %s -check-prefix=SECTIONS
11
12# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
13# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
14# RUN: ld.lld -shared %t2.o -o %t3.so
15# RUN: ld.lld --no-toc-optimize %t.o %t3.so -o %t
16# RUN: llvm-objdump -d -start-address=0x10010000 -stop-address=0x10010018 %t | FileCheck %s -check-prefix=CALLEE_DUMP
17# RUN: llvm-objdump -d -start-address=0x12010020 -stop-address=0x12010084 %t | FileCheck %s -check-prefix=CALLER_DUMP
18# RUN: llvm-objdump -D -start-address=0x12020008 -stop-address=0x12020010 %t | FileCheck %s -check-prefix=BRANCH_LT_BE
19# RUN: llvm-readelf --sections %t | FileCheck %s -check-prefix=SECTIONS
20
21 .text
22 .abiversion 2
23 .protected callee
24 .globl callee
25 .p2align 4
26 .type callee,@function
27callee:
28.Lfunc_gep0:
29 addis 2, 12, .TOC.-.Lfunc_gep0@ha
30 addi 2, 2, .TOC.-.Lfunc_gep0@l
31.Lfunc_lep0:
32 .localentry callee, .Lfunc_lep0-.Lfunc_gep0
33 addis 4, 2, .LC0@toc@ha
34 ld 4, .LC0@toc@l(4)
35 lwz 3, 0(4)
36 blr
37
38 .space 0x2000000
39
40 .protected _start
41 .global _start
42 .p2align 4
43 .type _start,@function
44_start:
45.Lfunc_begin1:
46.Lfunc_gep1:
47 addis 2, 12, .TOC.-.Lfunc_gep1@ha
48 addi 2, 2, .TOC.-.Lfunc_gep1@l
49.Lfunc_lep1:
50 .localentry _start, .Lfunc_lep1-.Lfunc_gep1
51 mflr 0
52 std 0, 16(1)
53 stdu 1, -32(1)
54 bl callee
55 bl foo_external_diff
56 nop
57 addi 1, 1, 32
58 ld 0, 16(1)
59 mtlr 0
60
61 addis 4, 2, .LC1@toc@ha
62 ld 4, .LC1@toc@l(4)
63 lwz 4, 0(4)
64 add 3, 3, 4
65 blr
66
67
68 .section .toc,"aw",@progbits
69.LC0:
70 .tc a[TC],a
71.LC1:
72 .tc b[TC],b
73
74
75 .data
76 .type a,@object
77 .globl a
78 .p2align 2
79a:
80 .long 11
81 .size a, 4
82
83 .type b,@object
84 .global b
85 .p2align 2
86b:
87 .long 33
88 .size b, 4
89
90# Verify address of the callee
91# CALLEE_DUMP: callee:
92# CALLEE_DUMP: 10010000: {{.*}} addis 2, 12, 515
93# CALLEE_DUMP: 10010004: {{.*}} addi 2, 2, -32544
94# CALLEE_DUMP: 10010008: {{.*}} addis 4, 2, 0
95
96# Verify the address of _start, and the call to the long-branch thunk.
97# CALLER_DUMP: _start:
98# CALLER_DUMP: 12010020: {{.*}} addis 2, 12, 3
99# CALLER_DUMP: 12010038: {{.*}} bl .+56
100
101# Verify the thunks contents: TOC-pointer + offset = .branch_lt[0]
102# 0x120380e8 + (-2 << 16 + 32552) = 0x12020008
103# CALLER_DUMP: __long_branch_callee:
104# CALLER_DUMP: 12010060: {{.*}} addis 12, 2, -2
105# CALLER_DUMP: 12010064: {{.*}} ld 12, 32552(12)
106# CALLER_DUMP: 12010068: {{.*}} mtctr 12
107# CALLER_DUMP: 1201006c: {{.*}} bctr
108
109# BRANCH_LT_LE: Disassembly of section .branch_lt:
110# BRANCH_LT_LE-NEXT: .branch_lt:
111# BRANCH_LT_LE-NEXT: 12020008: 08 00 01 10
112# BRANCH_LT_LE-NEXT: 1202000c: 00 00 00 00
113
114# BRANCH_LT_BE: Disassembly of section .branch_lt:
115# BRANCH_LT_BE-NEXT: .branch_lt:
116# BRANCH_LT_BE-NEXT: 12020008: 00 00 00 00
117# BRANCH_LT_BE-NEXT: 1202000c: 10 01 00 08
118
119# [Nr] Name Type Address Off Size
120# SECTIONS: [ 9] .branch_lt PROGBITS 0000000012020008 2020008 000008
121# SECTIONS: [11] .got PROGBITS 00000000120300e0 20300e0 000008
deps/lld/test/ELF/ppc64-rel-so-local-calls.s+2-2
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1// REQUIRES: ppc1// REQUIRES: ppc
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared -z notext %t.o -o %t.so4// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s5// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
66
7// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o7// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
8// RUN: ld.lld -shared -z notext %t.o -o %t.so8// RUN: ld.lld -shared %t.o -o %t.so
9// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s9// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
1010
1111
deps/lld/test/ELF/ppc64-relocs.s+30-19
...@@ -63,7 +63,7 @@ _start:...@@ -63,7 +63,7 @@ _start:
6363
64# CHECK: Disassembly of section .R_PPC64_TOC16_HA:64# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
65# CHECK: .FR_PPC64_TOC16_HA:65# CHECK: .FR_PPC64_TOC16_HA:
66# CHECK: 10010018: {{.*}} addis 1, 2, 066# CHECK: 10010018: {{.*}} nop
6767
68.section .R_PPC64_REL24,"ax",@progbits68.section .R_PPC64_REL24,"ax",@progbits
69.globl .FR_PPC64_REL2469.globl .FR_PPC64_REL24
...@@ -76,6 +76,17 @@ _start:...@@ -76,6 +76,17 @@ _start:
76# CHECK: .FR_PPC64_REL24:76# CHECK: .FR_PPC64_REL24:
77# CHECK: 1001001c: {{.*}} b .+477# CHECK: 1001001c: {{.*}} b .+4
7878
79.section .R_PPC64_REL14,"ax",@progbits
80.globl .FR_PPC64_REL14
81.FR_PPC64_REL14:
82 beq .Lfooy
83.section .R_PPC64_REL14_2,"ax",@progbits
84.Lfooy:
85
86# CHECK: Disassembly of section .R_PPC64_REL14:
87# CHECK: .FR_PPC64_REL14:
88# CHECK: 10010020: {{.*}} bt 2, .+4
89
79.section .R_PPC64_ADDR16_LO,"ax",@progbits90.section .R_PPC64_ADDR16_LO,"ax",@progbits
80.globl .FR_PPC64_ADDR16_LO91.globl .FR_PPC64_ADDR16_LO
81.FR_PPC64_ADDR16_LO:92.FR_PPC64_ADDR16_LO:
...@@ -83,7 +94,7 @@ _start:...@@ -83,7 +94,7 @@ _start:
8394
84# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:95# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
85# CHECK: .FR_PPC64_ADDR16_LO:96# CHECK: .FR_PPC64_ADDR16_LO:
86# CHECK: 10010020: {{.*}} li 1, 097# CHECK: 10010024: {{.*}} li 1, 0
8798
88.section .R_PPC64_ADDR16_HI,"ax",@progbits99.section .R_PPC64_ADDR16_HI,"ax",@progbits
89.globl .FR_PPC64_ADDR16_HI100.globl .FR_PPC64_ADDR16_HI
...@@ -92,7 +103,7 @@ _start:...@@ -92,7 +103,7 @@ _start:
92103
93# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:104# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
94# CHECK: .FR_PPC64_ADDR16_HI:105# CHECK: .FR_PPC64_ADDR16_HI:
95# CHECK: 10010024: {{.*}} li 1, 4097106# CHECK: 10010028: {{.*}} li 1, 4097
96107
97.section .R_PPC64_ADDR16_HA,"ax",@progbits108.section .R_PPC64_ADDR16_HA,"ax",@progbits
98.globl .FR_PPC64_ADDR16_HA109.globl .FR_PPC64_ADDR16_HA
...@@ -101,7 +112,7 @@ _start:...@@ -101,7 +112,7 @@ _start:
101112
102# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:113# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
103# CHECK: .FR_PPC64_ADDR16_HA:114# CHECK: .FR_PPC64_ADDR16_HA:
104# CHECK: 10010028: {{.*}} li 1, 4097115# CHECK: 1001002c: {{.*}} li 1, 4097
105116
106.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits117.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
107.globl .FR_PPC64_ADDR16_HIGHER118.globl .FR_PPC64_ADDR16_HIGHER
...@@ -110,7 +121,7 @@ _start:...@@ -110,7 +121,7 @@ _start:
110121
111# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:122# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
112# CHECK: .FR_PPC64_ADDR16_HIGHER:123# CHECK: .FR_PPC64_ADDR16_HIGHER:
113# CHECK: 1001002c: {{.*}} li 1, 0124# CHECK: 10010030: {{.*}} li 1, 0
114125
115.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits126.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
116.globl .FR_PPC64_ADDR16_HIGHERA127.globl .FR_PPC64_ADDR16_HIGHERA
...@@ -119,7 +130,7 @@ _start:...@@ -119,7 +130,7 @@ _start:
119130
120# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:131# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
121# CHECK: .FR_PPC64_ADDR16_HIGHERA:132# CHECK: .FR_PPC64_ADDR16_HIGHERA:
122# CHECK: 10010030: {{.*}} li 1, 0133# CHECK: 10010034: {{.*}} li 1, 0
123134
124.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits135.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
125.globl .FR_PPC64_ADDR16_HIGHEST136.globl .FR_PPC64_ADDR16_HIGHEST
...@@ -128,7 +139,7 @@ _start:...@@ -128,7 +139,7 @@ _start:
128139
129# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:140# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
130# CHECK: .FR_PPC64_ADDR16_HIGHEST:141# CHECK: .FR_PPC64_ADDR16_HIGHEST:
131# CHECK: 10010034: {{.*}} li 1, 0142# CHECK: 10010038: {{.*}} li 1, 0
132143
133.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits144.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
134.globl .FR_PPC64_ADDR16_HIGHESTA145.globl .FR_PPC64_ADDR16_HIGHESTA
...@@ -137,7 +148,7 @@ _start:...@@ -137,7 +148,7 @@ _start:
137148
138# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:149# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
139# CHECK: .FR_PPC64_ADDR16_HIGHESTA:150# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
140# CHECK: 10010038: {{.*}} li 1, 0151# CHECK: 1001003c: {{.*}} li 1, 0
141152
142.section .R_PPC64_REL32, "ax",@progbits153.section .R_PPC64_REL32, "ax",@progbits
143.globl .FR_PPC64_REL32154.globl .FR_PPC64_REL32
...@@ -149,20 +160,20 @@ _start:...@@ -149,20 +160,20 @@ _start:
149160
150# DATALE: Disassembly of section .rodata:161# DATALE: Disassembly of section .rodata:
151# DATALE: .rodata:162# DATALE: .rodata:
152# DATALE: 10000190: b4 fe 00 00163# DATALE: 10000190: b8 fe 00 00
153164
154# DATABE: Disassembly of section .rodata:165# DATABE: Disassembly of section .rodata:
155# DATABE: .rodata:166# DATABE: .rodata:
156# DATABE: 10000190: 00 00 fe b4167# DATABE: 10000190: 00 00 fe b8
157168
158# Address of rodata + value stored at rodata entry169# Address of rodata + value stored at rodata entry
159# should equal address of LBB0_2.170# should equal address of LBB0_2.
160# 0x10000190 + 0xfeb4 = 0x10010044171# 0x10000190 + 0xfeb4 = 0x10010044
161# CHECK: Disassembly of section .R_PPC64_REL32:172# CHECK: Disassembly of section .R_PPC64_REL32:
162# CHECK: .FR_PPC64_REL32:173# CHECK: .FR_PPC64_REL32:
163# CHECK: 1001003c: {{.*}} addis 5, 2, 0174# CHECK: 10010040: {{.*}} nop
164# CHECK: 10010040: {{.*}} ld 5, -32736(5)175# CHECK: 10010044: {{.*}} ld 5, -32736(2)
165# CHECK: 10010044: {{.*}} add 3, 3, 4176# CHECK: 10010048: {{.*}} add 3, 3, 4
166177
167.section .R_PPC64_REL64, "ax",@progbits178.section .R_PPC64_REL64, "ax",@progbits
168.globl .FR_PPC64_REL64179.globl .FR_PPC64_REL64
...@@ -178,16 +189,16 @@ __foo:...@@ -178,16 +189,16 @@ __foo:
178189
179# Check that address of eh_frame entry + value stored190# Check that address of eh_frame entry + value stored
180# should equal the address of foo. Since it is not aligned,191# should equal the address of foo. Since it is not aligned,
181# the entry is not stored exactly at 100001a8. It starts at192# the entry is not stored exactly at 10000198. It starts at
182# address 0x100001aa and has the value 0xfeaa.193# address 0x1000019a and has the value 0xfeaa.
183# 0x100001aa + 0xfeaa = 0x10010054194# 0x100001aa + 0xfeae = 0x10010058
184# DATALE: Disassembly of section .eh_frame:195# DATALE: Disassembly of section .eh_frame:
185# DATALE: .eh_frame:196# DATALE: .eh_frame:
186# DATALE: 100001a8: {{.*}} aa fe197# DATALE: 100001a8: {{.*}} ae fe
187198
188# DATABE: Disassembly of section .eh_frame:199# DATABE: Disassembly of section .eh_frame:
189# DATABE: .eh_frame:200# DATABE: .eh_frame:
190# DATABE: 100001b0: fe aa {{.*}}201# DATABE: 100001b0: fe ae {{.*}}
191202
192# CHECK: __foo203# CHECK: __foo
193# CHECK-NEXT: 10010054: {{.*}} li 3, 0204# CHECK-NEXT: 10010058: {{.*}} li 3, 0
deps/lld/test/ELF/ppc64-shared-long_branch.s created+114
...@@ -0,0 +1,114 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld --no-toc-optimize -shared %t.o -o %t
5# RUN: llvm-objdump -d -start-address=0x10000 -stop-address=0x10018 %t | FileCheck %s -check-prefix=CALLEE_DUMP
6# RUN: llvm-objdump -d -start-address=0x2010020 -stop-address=0x2010070 %t | FileCheck %s -check-prefix=CALLER_DUMP
7# RUN: llvm-readelf --sections %t | FileCheck %s -check-prefix=SECTIONS
8# RUN: llvm-readelf --relocations %t | FileCheck %s -check-prefix=DYNRELOC
9
10
11# _start calls protected function callee. Since callee is protected no plt stub
12# is needed. The binary however has been padded out with space so that the call
13# distance is further then a bl instrution can reach.
14
15 .text
16 .abiversion 2
17 .protected callee
18 .global callee
19 .p2align 4
20 .type callee,@function
21callee:
22.Lfunc_gep0:
23 addis 2, 12, .TOC.-.Lfunc_gep0@ha
24 addi 2, 2, .TOC.-.Lfunc_gep0@l
25.Lfunc_lep0:
26 .localentry callee, .Lfunc_lep0-.Lfunc_gep0
27 addis 4, 2, .LC0@toc@ha
28 ld 4, .LC0@toc@l(4)
29 lwz 3, 0(4)
30 blr
31
32 .space 0x2000000
33
34 .protected _start
35 .globl _start
36 .p2align 4
37 .type _start,@function
38_start:
39.Lfunc_begin1:
40.Lfunc_gep1:
41 addis 2, 12, .TOC.-.Lfunc_gep1@ha
42 addi 2, 2, .TOC.-.Lfunc_gep1@l
43.Lfunc_lep1:
44 .localentry _start, .Lfunc_lep1-.Lfunc_gep1
45 mflr 0
46 std 0, 16(1)
47 stdu 1, -32(1)
48 bl callee
49 bl ext_callee
50 nop
51 addi 1, 1, 32
52 ld 0, 16(1)
53 mtlr 0
54
55 addis 4, 2, .LC1@toc@ha
56 ld 4, .LC1@toc@l(4)
57 lwz 4, 0(4)
58 add 3, 3, 4
59 blr
60
61
62 .section .toc,"aw",@progbits
63.LC0:
64 .tc a[TC],a
65.LC1:
66 .tc b[TC],b
67
68
69 .data
70 .type a,@object
71 .globl a
72 .p2align 2
73a:
74 .long 11
75 .size a, 4
76
77 .type b,@object
78 .globl b
79 .p2align 2
80b:
81 .long 33
82 .size b, 4
83
84# Verify address of the callee
85# CALLEE_DUMP: callee:
86# CALLEE_DUMP: 10000: {{.*}} addis 2, 12, 515
87# CALLEE_DUMP: 10004: {{.*}} addi 2, 2, -32528
88# CALLEE_DUMP: 10008: {{.*}} addis 4, 2, 0
89
90# Verify the address of _start, and the call to the long-branch thunk.
91# CALLER_DUMP: _start:
92# CALLER_DUMP: 2010020: {{.*}} addis 2, 12, 3
93# CALLER_DUMP: 2010038: {{.*}} bl .+56
94
95# Verify the thunks contents: TOC-pointer + offset = .branch_lt[0]
96# 0x20380F0 + 32552 = 0x2040018
97# CALLER_DUMP: __long_branch_callee:
98# CALLER_DUMP: 2010060: {{.*}} addis 12, 2, 0
99# CALLER_DUMP: 2010064: {{.*}} ld 12, 32552(12)
100# CALLER_DUMP: 2010068: {{.*}} mtctr 12
101# CALLER_DUMP: 201006c: {{.*}} bctr
102
103# .got section is at address 0x20300f0 so TOC pointer points to 0x20400F0.
104# .plt section has a 2 entry header and a single entry for the long branch.
105# [Nr] Name Type Address Off Size
106# SECTIONS: [11] .got PROGBITS 00000000020300f0 20300f0 000008
107# SECTIONS: [13] .plt NOBITS 0000000002040000 2030108 000018
108# SECTIONS: [14] .branch_lt NOBITS 0000000002040018 2030108 000008
109
110# There is a relative dynamic relocation for (.plt + 16 bytes), with a base
111# address equal to callees local entry point (0x10000 + 8).
112# DYNRELOC: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 3 entries:
113# DYNRELOC: Offset Info Type Symbol's Value
114# DYNRELOC: 0000000002040018 0000000000000016 R_PPC64_RELATIVE 10008
deps/lld/test/ELF/ppc64-split-stack-adjust-fail.s created+53
...@@ -0,0 +1,53 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
5
6# RUN: not ld.lld --defsym __morestack=0x10010000 %t1.o %t2.o -o %t 2>&1 | FileCheck %s
7
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
10
11# RUN: not ld.lld --defsym __morestack=0x10010000 %t1.o %t2.o -o %t 2>&1 | FileCheck %s
12
13# CHECK: error: {{.*}}.o:(.text): wrong_regs (with -fsplit-stack) calls nss_callee (without -fsplit-stack), but couldn't adjust its prologue
14
15 .abiversion 2
16 .section ".text"
17
18 .p2align 2
19 .global wrong_regs
20 .type wrong_regs, @function
21
22wrong_regs:
23.Lwr_gep:
24 addis 2, 12, .TOC.-.Lwr_gep@ha
25 addi 2, 2, .TOC.-.Lwr_gep@l
26 .localentry wrong_regs, .-wrong_regs
27 ld 0, -0x7040(13)
28 addis 5, 2, -1
29 addi 5, 5, -32
30 addi 12, 1, -32
31 nop
32 cmpld 7, 12, 0
33 blt- 7, .Lwr_alloc_more
34.Lwr_body:
35 mflr 0
36 std 0, 16(1)
37 stdu 1, -32(1)
38 bl nss_callee
39 addi 1, 1, 32
40 ld 0, 16(1)
41 mtlr 0
42 blr
43.Lwr_alloc_more:
44 mflr 0
45 std 0, 16(1)
46 bl __morestack
47 ld 0, 16(1)
48 mtlr 0
49 blr
50 b .Lwr_body
51 .size wrong_regs, .-wrong_regs
52
53 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/ppc64-split-stack-adjust-overflow.s created+64
...@@ -0,0 +1,64 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
5
6# RUN: not ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 2>&1 | \
7# RUN: FileCheck -check-prefix=OVERFLOW %s
8# RUN: not ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 \
9# RUN: -split-stack-adjust-size 4097 2>&1 | FileCheck -check-prefix=OVERFLOW %s
10# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
11# RUN: llvm-objdump -d %t | FileCheck %s
12
13# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
14# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
15
16# RUN: not ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 2>&1 | \
17# RUN: FileCheck -check-prefix=OVERFLOW %s
18# RUN: not ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 \
19# RUN: -split-stack-adjust-size 4097 2>&1 | FileCheck -check-prefix=OVERFLOW %s
20# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
21# RUN: llvm-objdump -d %t | FileCheck %s
22
23# OVERFLOW: error: {{.*}}.o:(function caller: .text+0x8): split-stack prologue adjustment overflows
24
25 .p2align 2
26 .global caller
27 .type caller, @function
28caller:
29.Lcaller_gep:
30 addis 2, 12, .TOC.-.Lcaller_gep@ha
31 addi 2, 2, .TOC.-.Lcaller_gep@l
32 .localentry caller, .-caller
33 ld 0, -0x7040(13)
34 addis 12, 1, -32768
35 addi 12, 12, 4096
36 cmpld 7, 12, 0
37 blt- 7, .Lcaller_alloc_more
38.Lcaller_body:
39 mflr 0
40 std 0, 16(1)
41 stdu 1, -32(1)
42 bl nss_callee
43 addi 1, 1, 32
44 ld 0, 16(1)
45 mtlr 0
46 blr
47.Lcaller_alloc_more:
48 mflr 0
49 std 0, 16(1)
50 bl __morestack
51 ld 0, 16(1)
52 mtlr 0
53 blr
54 b .Lcaller_body
55 .size caller, .-caller
56
57# CHECK-LABEL: caller
58# CHECK: ld 0, -28736(13)
59# CHECK-NEXT: addis 12, 1, -32768
60# CHECK-NEXT: nop
61# CHECK-NEXT: cmpld 7, 12, 0
62# CHECK-NEXT: bt- 28, .+36
63
64.section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/ppc64-split-stack-adjust-size-success.s created+108
...@@ -0,0 +1,108 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
5
6# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 32768
7# RUN: llvm-objdump -d %t | FileCheck %s
8# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
9# RUN: llvm-objdump -d %t | FileCheck %s -check-prefix=SMALL
10# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 0
11# RUN: llvm-objdump -d %t | FileCheck %s -check-prefix=ZERO
12# RUN: not ld.lld %t1.o %t2.o -o %t -split-stack-adjust-size -1 2>&1 | FileCheck %s -check-prefix=ERR
13# ERR: error: --split-stack-adjust-size: size must be >= 0
14
15# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
16# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
17
18# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 32768
19# RUN: llvm-objdump -d %t | FileCheck %s
20# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
21# RUN: llvm-objdump -d %t | FileCheck %s -check-prefix=SMALL
22# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 0
23# RUN: llvm-objdump -d %t | FileCheck %s -check-prefix=ZERO
24 .p2align 2
25 .global caller
26 .type caller, @function
27caller:
28.Lcaller_gep:
29 addis 2, 12, .TOC.-.Lcaller_gep@ha
30 addi 2, 2, .TOC.-.Lcaller_gep@l
31 .localentry caller, .-caller
32 ld 0, -0x7040(13)
33 addi 12, 1, -32
34 nop
35 cmpld 7, 12, 0
36 blt- 7, .Lcaller_alloc_more
37.Lcaller_body:
38 mflr 0
39 std 0, 16(1)
40 stdu 1, -32(1)
41 bl nss_callee
42 addi 1, 1, 32
43 ld 0, 16(1)
44 mtlr 0
45 blr
46.Lcaller_alloc_more:
47 mflr 0
48 std 0, 16(1)
49 bl __morestack
50 ld 0, 16(1)
51 mtlr 0
52 blr
53 b .Lcaller_body
54 .size caller, .-caller
55
56# CHECK-LABEL: caller
57# CHECK: ld 0, -28736(13)
58# CHECK-NEXT: addis 12, 1, -1
59# CHECK-NEXT: addi 12, 12, 32736
60# CHECK-NEXT: cmpld 7, 12, 0
61# CHECK-NEXT: bt- 28, .+36
62
63# SMALL-LABEL: caller
64# SMALL: ld 0, -28736(13)
65# SMALL-NEXT: addi 12, 1, -4128
66# SMALL-NEXT: nop
67# SMALL-NEXT: cmpld 7, 12, 0
68# SMALL-NEXT: bt- 28, .+36
69
70# ZERO-LABEL: caller
71# ZERO: ld 0, -28736(13)
72# ZERO-NEXT: addi 12, 1, -32
73# ZERO-NEXT: nop
74# ZERO-NEXT: cmpld 7, 12, 0
75# ZERO-NEXT: bt- 28, .+36
76 .p2align 2
77 .global main
78 .type main, @function
79main:
80.Lmain_gep:
81 addis 2,12,.TOC.-.Lmain_gep@ha
82 addi 2,2,.TOC.-.Lmain_gep@l
83 .localentry main,.-main
84 ld 0,-0x7040(13)
85 addi 12,1,-32
86 nop
87 cmpld 7,12,0
88 blt- 7, .Lmain_morestack
89.Lmain_body:
90 mflr 0
91 std 0, 16(1)
92 stdu 1, -32(1)
93 bl caller
94 addi 1, 1, 32
95 ld 0, 16(1)
96 mtlr 0
97 blr
98.Lmain_morestack:
99 mflr 0
100 std 0, 16(1)
101 bl __morestack
102 ld 0, 16(1)
103 mtlr 0
104 blr
105 b .Lmain_body
106 .size main,.-main
107
108 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/ppc64-split-stack-prologue-adjust-success.s created+224
...@@ -0,0 +1,224 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
5# RUN: ld.lld --defsym __morestack=0x10010000 %t1.o %t2.o -o %t
6# RUN: llvm-objdump -d %t | FileCheck %s
7
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-no-split-stack.s -o %t2.o
10# RUN: ld.lld --defsym __morestack=0x10010000 %t1.o %t2.o -o %t
11# RUN: llvm-objdump -d %t | FileCheck %s
12
13 .abiversion 2
14 .section ".text"
15
16
17# A caller with a stack that is small enough that the addis instruction
18# from the split-stack prologue is unneeded, and after the prologue adjustment
19# the stack size still fits whithin 16 bits.
20 .p2align 2
21 .global caller_small_stack
22 .type caller_small_stack, @function
23caller_small_stack:
24.Lcss_gep:
25 addis 2, 12, .TOC.-.Lcss_gep@ha
26 addi 2, 2, .TOC.-.Lcss_gep@l
27 .localentry caller_small_stack, .-caller_small_stack
28 ld 0, -0x7040(13)
29 addi 12, 1, -32
30 nop
31 cmpld 7, 12, 0
32 blt- 7, .Lcss_alloc_more
33.Lcss_body:
34 mflr 0
35 std 0, 16(1)
36 stdu 1, -32(1)
37 bl nss_callee
38 addi 1, 1, 32
39 ld 0, 16(1)
40 mtlr 0
41 blr
42.Lcss_alloc_more:
43 mflr 0
44 std 0, 16(1)
45 bl __morestack
46 ld 0, 16(1)
47 mtlr 0
48 blr
49 b .Lcss_body
50 .size caller_small_stack, .-caller_small_stack
51
52# CHECK-LABEL: caller_small_stack
53# CHECK: ld 0, -28736(13)
54# CHECK-NEXT: addi 12, 1, -16416
55# CHECK-NEXT: nop
56# CHECK-NEXT: cmpld 7, 12, 0
57# CHECK-NEXT: bt- 28, .+36
58
59# A caller that has a stack size that fits whithin 16 bits, but the adjusted
60# stack size after prologue adjustment now overflows 16 bits needing both addis
61# and addi instructions.
62 .p2align 2
63 .global caller_med_stack
64 .type caller_med_stack, @function
65caller_med_stack:
66.Lcms_gep:
67 addis 2, 12, .TOC.-.Lcms_gep@ha
68 addi 12, 12, .TOC.-.Lcms_gep@l
69 .localentry caller_med_stack, .-caller_med_stack
70 ld 0, -0x7040(13)
71 addi 12, 1, -32764
72 nop
73 cmpld 7, 12, 0
74 blt- 7, .Lcms_alloc_more
75.Lcms_body:
76 mflr 0
77 std 0, 16(1)
78 stdu 1, -32764(1)
79 bl nss_callee
80 addi 1, 1, 32764
81 ld 0, 16(1)
82 mtlr 0
83 blr
84.Lcms_alloc_more:
85 mflr 0
86 std 0, 16(1)
87 bl __morestack
88 ld 0, 16(1)
89 mtlr 0
90 blr
91 b .Lcms_body
92 .size caller_med_stack, .-caller_med_stack
93
94# A caller with a large enough stack frame that both the addis and
95# addi instructions are used in the split-stack prologue.
96 .p2align 2
97 .global caller_large_stack
98 .type caller_large_stack, @function
99caller_large_stack:
100.Lcls_gep:
101 addis 2, 12, .TOC.-.Lcls_gep@ha
102 addi 12, 12, .TOC.-.Lcls_gep@l
103 .localentry caller_large_stack, .-caller_large_stack
104 ld 0, -0x7040(13)
105 addis 12, 1, -1
106 addi 12, 12, -32
107 cmpld 7, 12, 0
108 blt- 7, .Lcls_alloc_more
109.Lcls_body:
110 mflr 0
111 std 0, 16(1)
112 lis 0, -1
113 addi 0, 0, -32
114 stdux 1, 0, 1
115 bl nss_callee
116 ld 1, 0(1)
117 ld 0, 16(1)
118 mtlr 0
119 blr
120.Lcls_alloc_more:
121 mflr 0
122 std 0, 16(1)
123 bl __morestack
124 ld 0, 16(1)
125 mtlr 0
126 blr
127 b .Lcls_body
128 .size caller_large_stack, .-caller_large_stack
129
130# CHECK-LABEL: caller_large_stack
131# CHECK: ld 0, -28736(13)
132# CHECK-NEXT: addis 12, 1, -1
133# CHECK-NEXT: addi 12, 12, -16416
134# CHECK-NEXT: cmpld 7, 12, 0
135# CHECK-NEXT: bt- 28, .+44
136
137# A caller with a stack size that is larger then 16 bits, but aligned such that
138# the addi instruction is unneeded.
139 .p2align 2
140 .global caller_large_aligned_stack
141 .type caller_large_aligned_stack, @function
142caller_large_aligned_stack:
143.Lclas_gep:
144 addis 2, 12, .TOC.-.Lclas_gep@ha
145 addi 12, 12, .TOC.-.Lclas_gep@l
146 .localentry caller_large_aligned_stack, .-caller_large_aligned_stack
147 ld 0, -0x7040(13)
148 addis 12, 1, -2
149 nop
150 cmpld 7, 12, 0
151 blt- 7, .Lclas_alloc_more
152.Lclas_body:
153 mflr 0
154 std 0, 16(1)
155 lis 0, -2
156 stdux 1, 0, 1
157 bl nss_callee
158 ld 1, 0(1)
159 ld 0, 16(1)
160 mtlr 0
161 blr
162.Lclas_alloc_more:
163 mflr 0
164 std 0, 16(1)
165 bl __morestack
166 ld 0, 16(1)
167 mtlr 0
168 blr
169 b .Lclas_body
170 .size caller_large_aligned_stack, .-caller_large_aligned_stack
171
172# CHECK-LABEL: caller_large_aligned_stack
173# CHECK: ld 0, -28736(13)
174# CHECK-NEXT: addis 12, 1, -2
175# CHECK-NEXT: addi 12, 12, -16384
176# CHECK-NEXT: cmpld 7, 12, 0
177# CHECK-NEXT: bt- 28, .+40
178
179# main only calls split-stack functions or __morestack so
180# there should be no adjustment of its split-stack prologue.
181 .p2align 2
182 .global main
183 .type main, @function
184main:
185.Lmain_gep:
186 addis 2, 12,.TOC.-.Lmain_gep@ha
187 addi 2, 2,.TOC.-.Lmain_gep@l
188 .localentry main,.-main
189 ld 0, -0x7040(13)
190 addi 12,1,-32
191 nop
192 cmpld 7, 12,0
193 blt- 7, .Lmain_morestack
194.Lmain_body:
195 mflr 0
196 std 0, 16(1)
197 stdu 1, -32(1)
198 bl caller_small_stack
199 nop
200 bl caller_med_stack
201 nop
202 bl caller_large_stack
203 nop
204 bl caller_large_aligned_stack
205 addi 1, 1, 32
206 ld 0, 16(1)
207 mtlr 0
208 blr
209.Lmain_morestack:
210 mflr 0
211 std 0, 16(1)
212 bl __morestack
213 ld 0, 16(1)
214 mtlr 0
215 blr
216 b .Lmain_body
217 .size main,.-main
218# CHECK-LABEL: main
219# CHECK: ld 0, -28736(13)
220# CHECK-NEXT: addi 12, 1, -32
221# CHECK-NEXT: nop
222# CHECK-NEXT: cmpld 7, 12, 0
223
224 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/ppc64-tls-gd-le-small.s created+61
...@@ -0,0 +1,61 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-objdump -d -r %t.o | FileCheck --check-prefix=CHECK-INPUT %s
5# RUN: ld.lld --defsym __tls_get_addr=0x10001000 %t.o -o %t
6# RUN: llvm-objdump -d %t | FileCheck --check-prefix=CHECK-DIS %s
7# RUN: llvm-readelf -relocations %t | FileCheck --check-prefix=DYN-RELOCS %s
8
9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10# RUN: llvm-objdump -d -r %t.o | FileCheck --check-prefix=CHECK-INPUT %s
11# RUN: ld.lld --defsym __tls_get_addr=0x10001000 %t.o -o %t
12# RUN: llvm-objdump -d %t | FileCheck --check-prefix=CHECK-DIS %s
13# RUN: llvm-readelf -relocations %t | FileCheck --check-prefix=DYN-RELOCS %s
14
15# Test checks the relaxation of a 'small' general-dynamic tls access into a
16# local-exec tls access.
17
18 .text
19 .abiversion 2
20
21 .global test
22 .p2align 4
23 .type test, @function
24
25test:
26.Lgep:
27 addis 2, 12, .TOC.-.Lgep@ha
28 addi 2, 2, .TOC.-.Lgep@l
29 .localentry test, .-test
30 mflr 0
31 std 0, 16(1)
32 stdu 1, -32(1)
33 addi 3, 2, a@got@tlsgd
34 bl __tls_get_addr(a@tlsgd)
35 nop
36 lwz 3, 0(3)
37 addi 1, 1, 32
38 ld 0, 16(1)
39 mtlr 0
40 blr
41
42 .type a, @object
43 .section .tdata,"awT",@progbits
44 .global a
45 .p2align 2
46a:
47 .long 55
48 .size a, 4
49
50# CHECK-INPUT: addi 3, 2, 0
51# CHECK-INPUT-NEXT: R_PPC64_GOT_TLSGD16 a
52# CHECK-INPUT-NEXT: bl .+0
53# CHECK-INPUT-NEXT: R_PPC64_TLSGD a
54# CHECK-INPUT-NEXT: R_PPC64_REL24 __tls_get_addr
55
56# CHECK-DIS: addis 3, 13, 0
57# CHECK-DIS-NEXT: nop
58# CHECK-DIS-NEXT: addi 3, 3, -28672
59# CHECK-DIS-NEXT: lwz 3, 0(3)
60
61# DYN-RELOCS: There are no relocations in this file
deps/lld/test/ELF/ppc64-tls-gd-le.s+6-6
...@@ -1,16 +1,16 @@...@@ -1,16 +1,16 @@
1// REQUIRES: ppc1// REQUIRES: ppc
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: ld.lld %t.o -o %t5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
88
9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s10// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
11// RUN: ld.lld %t.o -o %t11// RUN: ld.lld %t.o -o %t
12// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s12// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s13// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1414
15 .text15 .text
16 .abiversion 216 .abiversion 2
deps/lld/test/ELF/ppc64-tls-ie-le.s created+140
...@@ -0,0 +1,140 @@
1// REQUIRES: ppc
2
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-tls-ie-le.s -o %t2.o
5// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o -o %t
6// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
8// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
9
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
11// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls-ie-le.s -o %t2.o
12// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o -o %t
13// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
14// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
15// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
16
17 .text
18 .abiversion 2
19test1: # @test1
20 addis 3, 2, c@got@tprel@ha
21 ld 3, c@got@tprel@l(3)
22 lbzx 3, 3, c@tls
23 blr
24test2: # @test2
25 addis 3, 2, s@got@tprel@ha
26 ld 3, s@got@tprel@l(3)
27 lhzx 3, 3, s@tls
28 blr
29test3: # @test3
30 addis 3, 2, i@got@tprel@ha
31 ld 3, i@got@tprel@l(3)
32 lwzx 3, 3, i@tls
33 blr
34test4: # @test4
35 addis 3, 2, l@got@tprel@ha
36 ld 3, l@got@tprel@l(3)
37 ldx 3, 3, l@tls
38 blr
39test5: # @test5
40 addis 4, 2, c@got@tprel@ha
41 ld 4, c@got@tprel@l(4)
42 stbx 3, 4, c@tls
43 blr
44test6: # @test6
45 addis 4, 2, s@got@tprel@ha
46 ld 4, s@got@tprel@l(4)
47 sthx 3, 4, s@tls
48 blr
49test7: # @test7
50 addis 4, 2, i@got@tprel@ha
51 ld 4, i@got@tprel@l(4)
52 stwx 3, 4, i@tls
53 blr
54test8: # @test8
55 addis 4, 2, l@got@tprel@ha
56 ld 4, l@got@tprel@l(4)
57 stdx 3, 4, l@tls
58 blr
59test9: # @test9
60 addis 3, 2, i@got@tprel@ha
61 ld 3, i@got@tprel@l(3)
62 add 3, 3, i@tls
63 blr
64test_ds: # @test_ds
65 ld 4, l@got@tprel(2)
66 stdx 3, 4, l@tls
67 blr
68
69
70// Verify that the input has initial-exec tls relocation types.
71// InputRelocs: Relocation section '.rela.text'
72// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} c + 0
73// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} c + 0
74// InputRelocs: R_PPC64_TLS {{0+}} c + 0
75// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} s + 0
76// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} s + 0
77// InputRelocs: R_PPC64_TLS {{0+}} s + 0
78// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} i + 0
79// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} i + 0
80// InputRelocs: R_PPC64_TLS {{0+}} i + 0
81// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} l + 0
82// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} l + 0
83// InputRelocs: R_PPC64_TLS {{0+}} l + 0
84// InputRelocs: R_PPC64_GOT_TPREL16_DS {{0+}} l + 0
85// InputRelocs: R_PPC64_TLS {{0+}} l + 0
86
87// Verify that no initial-exec relocations exist for the dynamic linker.
88// OutputRelocs-NOT: R_PPC64_TPREL64 {{0+}} c + 0
89// OutputRelocs-NPT: R_PPC64_TPREL64 {{0+}} s + 0
90// OutputRelocs-NOT: R_PPC64_TPREL64 {{0+}} i + 0
91// OutputRelocs-NOT: R_PPC64_TPREL64 {{0+}} l + 0
92
93// Dis: test1:
94// Dis: nop
95// Dis: addis 3, 13, 0
96// Dis: lbz 3, -28672(3)
97
98// Dis: test2:
99// Dis: nop
100// Dis: addis 3, 13, 0
101// Dis: lhz 3, -28670(3)
102
103// Dis: test3:
104// Dis: nop
105// Dis: addis 3, 13, 0
106// Dis: lwz 3, -28668(3)
107
108// Dis: test4:
109// Dis: nop
110// Dis: addis 3, 13, 0
111// Dis: ld 3, -28664(3)
112
113// Dis: test5:
114// Dis: nop
115// Dis: addis 4, 13, 0
116// Dis: stb 3, -28672(4)
117
118// Dis: test6:
119// Dis: nop
120// Dis: addis 4, 13, 0
121// Dis: sth 3, -28670(4)
122
123// Dis: test7:
124// Dis: nop
125// Dis: addis 4, 13, 0
126// Dis: stw 3, -28668(4)
127
128// Dis: test8:
129// Dis: nop
130// Dis: addis 4, 13, 0
131// Dis: std 3, -28664(4)
132
133// Dis: test9:
134// Dis: nop
135// Dis: addis 3, 13, 0
136// Dis: addi 3, 3, -28668
137
138// Dis: test_ds:
139// Dis: addis 4, 13, 0
140// Dis: std 3, -28664(4)
deps/lld/test/ELF/ppc64-tls-ld-le.s+6-6
...@@ -1,16 +1,16 @@...@@ -1,16 +1,16 @@
1// REQUIRES: ppc1// REQUIRES: ppc
22
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: ld.lld %t.o -o %t5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
88
9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s10// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
11// RUN: ld.lld %t.o -o %t11// RUN: ld.lld %t.o -o %t
12// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s12// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s13// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1414
15 .text15 .text
16 .abiversion 216 .abiversion 2
deps/lld/test/ELF/ppc64-toc-addis-nop-lqsq.s created+73
...@@ -0,0 +1,73 @@
1# REQUIRES: ppc
2
3# RUN: llvm-readelf -relocations --wide %p/Inputs/ppc64le-quadword-ldst.o | FileCheck --check-prefix=QuadInputRelocs %s
4
5# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
6# RUN: ld.lld -shared %t2.o -o %t2.so
7
8# RUN: ld.lld %t2.so %p/Inputs/ppc64le-quadword-ldst.o -o %t
9# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
10
11# RUN: ld.lld --no-toc-optimize %t2.so %p/Inputs/ppc64le-quadword-ldst.o -o %t
12# RUN: llvm-objdump -D %t | FileCheck --check-prefix=NoOpt %s
13
14# QuadInputRelocs: Relocation section '.rela.text'
15# QuadInputRelocs: R_PPC64_TOC16_LO_DS 0000000000000000 quadLd
16# QuadInputRelocs: R_PPC64_TOC16_LO_DS 0000000000000010 quadSt
17
18# The powerpc backend doesn't support the quadword load/store instructions yet.
19# So they are tested by linking against an object file assembled with
20# `as -mpower9 -o ppc64le-quadword-ldst.o in.s` and checking the encoding of
21# the unknown instructions in the dissasembly. Source used as input:
22#quads:
23#.Lbegin_quads:
24#.Lgep_quads:
25# addis 2, 12, .TOC.-.Lgep_quads@ha
26# addi 2, 2, .TOC.-.Lgep_quads@l
27#.Llep_quads:
28#.localentry quads, .Llep_quads-.Lgep_quads
29# addis 3, 2, quadLd@toc@ha
30# lq 4, quadLd@toc@l(3)
31# addis 3, 2, quadSt@toc@ha
32# stq 4, quadSt@toc@l(3)
33# blr
34#
35# .p2align 4
36# .global quadLd
37# .lcomm quadLd, 16
38#
39# .global quadSt
40# .lcomm quadSt, 16
41
42
43# e0 82 7f 70 decodes to | 111000 | 00100 | 00010 | 16-bit imm |
44# | 56 | 4 | 2 | 32624 |
45# which is `lq r4, 32624(r2)`
46# f8 82 7f 82 decodes to | 111110 | 00100 | 00010 | 14-bit imm | 10 |
47# | 62 | 4 | 2 | 8160 | 2 |
48# The immediate represents a word offset so this dissasembles to:
49# `stq r4, 32640(r2)`
50# Dis-LABEL: quads:
51# Dis-NEXT: addis
52# Dis-NEXT: addi
53# Dis-NEXT: nop
54# Dis-NEXT: 70 7f 82 e0 <unknown>
55# Dis-NEXT: nop
56# Dis-NEXT: 82 7f 82 f8 <unknown>
57# Dis-NEXT: blr
58
59# e0 83 7f 70 decodes to | 111000 | 00100 | 00011 | 16-bit imm |
60# | 56 | 4 | 3 | 32624 |
61# `lq r4, 32624(r3)`
62# f8 83 7f 82 decodes to | 111110 | 00100 | 00010 | 14-bit imm | 10 |
63# | 62 | 4 | 2 | 8160 | 2 |
64# `stq r4, 32640(r3)`
65# NoOpt-LABEL: quads:
66# NoOpt-NEXT: addis
67# NoOpt-NEXT: addi
68# NoOpt-NEXT: addis 3, 2, 0
69# NoOpt-NEXT: 70 7f 83 e0 <unknown>
70# NoOpt-NEXT: addis 3, 2, 0
71# NoOpt-NEXT: 82 7f 83 f8 <unknown>
72# NoOpt-NEXT: blr
73
deps/lld/test/ELF/ppc64-toc-addis-nop.s created+272
...@@ -0,0 +1,272 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
5
6# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
7# RUN: ld.lld -shared %t2.o -o %t2.so
8#
9# RUN: ld.lld %t2.so %t.o -o %t
10# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
11#
12# RUN: ld.lld --no-toc-optimize %t2.so %t.o -o %t
13# RUN: llvm-objdump -D %t | FileCheck --check-prefix=NoOpt %s
14
15# InputRelocs: Relocation section '.rela.text'
16# InputRelocs: R_PPC64_TOC16_HA
17# InputRelocs: R_PPC64_TOC16_LO
18# InputRelocs: R_PPC64_TOC16_LO_DS
19
20
21 .text
22 .abiversion 2
23
24 .global bytes
25 .p2align 4
26 .type bytes,@function
27bytes:
28.Lbytes_gep:
29 addis 2, 12, .TOC.-.Lbytes_gep@ha
30 addi 2, 2, .TOC.-.Lbytes_gep@l
31.Lbytes_lep:
32 .localentry bytes, .Lbytes_lep-.Lbytes_gep
33 addis 3, 2, byteLd@toc@ha
34 lbz 3, byteLd@toc@l(3)
35 addis 4, 2, byteSt@toc@ha
36 stb 3, byteSt@toc@l(4)
37 blr
38# Dis-LABEL: bytes
39# Dis-NEXT: addis
40# Dis-NEXT: addi
41# Dis-NEXT: nop
42# Dis-NEXT: lbz 3, 32624(2)
43# Dis-NEXT: nop
44# Dis-NEXT: stb 3, 32625(2)
45# Dis-NEXT: blr
46
47# NoOpt-LABEL: bytes
48# NoOpt-NEXT: addis
49# NoOpt-NEXT: addi
50# NoOpt-NEXT: addis 3, 2, 0
51# NoOpt-NEXT: lbz 3, 32624(3)
52# NoOpt-NEXT: addis 4, 2, 0
53# NoOpt-NEXT: stb 3, 32625(4)
54# NoOpt-NEXT: blr
55
56 .global halfs
57 .p2align 4
58 .type halfs,@function
59halfs:
60.Lhalfs_gep:
61 addis 2, 12, .TOC.-.Lhalfs_gep@ha
62 addi 2, 2, .TOC.-.Lhalfs_gep@l
63.Lhalfs_lep:
64 .localentry halfs, .Lhalfs_lep-.Lhalfs_gep
65 addis 3, 2, halfLd@toc@ha
66 lhz 3, halfLd@toc@l(3)
67 addis 4, 2, halfLd@toc@ha
68 lha 4, halfLd@toc@l(4)
69 addis 5, 2, halfSt@toc@ha
70 sth 4, halfSt@toc@l(5)
71 blr
72# Dis-LABEL: halfs
73# Dis-NEXT: addis
74# Dis-NEXT: addi
75# Dis-NEXT: nop
76# Dis-NEXT: lhz 3, 32626(2)
77# Dis-NEXT: nop
78# Dis-NEXT: lha 4, 32626(2)
79# Dis-NEXT: nop
80# Dis-NEXT: sth 4, 32628(2)
81# Dis-NEXT: blr
82
83# NoOpt-LABEL: halfs
84# NoOpt-NEXT: addis
85# NoOpt-NEXT: addi
86# NoOpt-NEXT: addis 3, 2, 0
87# NoOpt-NEXT: lhz 3, 32626(3)
88# NoOpt-NEXT: addis 4, 2, 0
89# NoOpt-NEXT: lha 4, 32626(4)
90# NoOpt-NEXT: addis 5, 2, 0
91# NoOpt-NEXT: sth 4, 32628(5)
92# NoOpt-NEXT: blr
93
94
95 .global words
96 .p2align 4
97 .type words,@function
98words:
99.Lwords_gep:
100 addis 2, 12, .TOC.-.Lwords_gep@ha
101 addi 2, 2, .TOC.-.Lwords_gep@l
102.Lwords_lep:
103 .localentry words, .Lwords_lep-.Lwords_gep
104 addis 3, 2, wordLd@toc@ha
105 lwz 3, wordLd@toc@l(3)
106 addis 4, 2, wordLd@toc@ha
107 lwa 4, wordLd@toc@l(4)
108 addis 5, 2, wordSt@toc@ha
109 stw 4, wordSt@toc@l(5)
110 blr
111# Dis-LABEL: words
112# Dis-NEXT: addis
113# Dis-NEXT: addi
114# Dis-NEXT: nop
115# Dis-NEXT: lwz 3, 32632(2)
116# Dis-NEXT: nop
117# Dis-NEXT: lwa 4, 32632(2)
118# Dis-NEXT: nop
119# Dis-NEXT: stw 4, 32636(2)
120# Dis-NEXT: blr
121
122# NoOpt-LABEL: words
123# NoOpt-NEXT: addis
124# NoOpt-NEXT: addi
125# NoOpt-NEXT: addis 3, 2, 0
126# NoOpt-NEXT: lwz 3, 32632(3)
127# NoOpt-NEXT: addis 4, 2, 0
128# NoOpt-NEXT: lwa 4, 32632(4)
129# NoOpt-NEXT: addis 5, 2, 0
130# NoOpt-NEXT: stw 4, 32636(5)
131# NoOpt-NEXT: blr
132
133 .global doublewords
134 .p2align 4
135 .type doublewords,@function
136doublewords:
137.Ldoublewords_gep:
138 addis 2, 12, .TOC.-.Ldoublewords_gep@ha
139 addi 2, 2, .TOC.-.Ldoublewords_gep@l
140.Ldoublewords_lep:
141 .localentry doublewords, .Ldoublewords_lep-.Ldoublewords_gep
142 addis 3, 2, dwordLd@toc@ha
143 ld 3, dwordLd@toc@l(3)
144 addis 4, 2, dwordSt@toc@ha
145 std 3, dwordSt@toc@l(4)
146 blr
147
148# Dis-LABEL: doublewords
149# Dis-NEXT: addis
150# Dis-NEXT: addi
151# Dis-NEXT: nop
152# Dis-NEXT: ld 3, 32640(2)
153# Dis-NEXT: nop
154# Dis-NEXT: std 3, 32648(2)
155# Dis-NEXT: blr
156
157# NoOpt-LABEL: doublewords
158# NoOpt-NEXT: addis
159# NoOpt-NEXT: addi
160# NoOpt-NEXT: addis 3, 2, 0
161# NoOpt-NEXT: ld 3, 32640(3)
162# NoOpt-NEXT: addis 4, 2, 0
163# NoOpt-NEXT: std 3, 32648(4)
164# NoOpt-NEXT: blr
165
166 .global vec_dq
167 .p2align 4
168 .type vec_dq,@function
169vec_dq:
170.Lvec_dq_gep:
171 addis 2, 12, .TOC.-.Lvec_dq_gep@ha
172 addi 2, 2, .TOC.-.Lvec_dq_gep@l
173.Lvec_dq_lep:
174 .localentry vec_dq, .Lvec_dq_lep-.Lvec_dq_gep
175 addis 3, 2, vecLd@toc@ha
176 lxv 3, vecLd@toc@l(3)
177 addis 3, 2, vecSt@toc@ha
178 stxv 3, vecSt@toc@l(3)
179 blr
180
181# Dis-LABEL: vec_dq
182# Dis-NEXT: addis
183# Dis-NEXT: addi
184# Dis-NEXT: nop
185# Dis-NEXT: lxv 3, 32656(2)
186# Dis-NEXT: nop
187# Dis-NEXT: stxv 3, 32672(2)
188# Dis-NEXT: blr
189
190# NoOpt-LABEL: vec_dq
191# NoOpt-NEXT: addis
192# NoOpt-NEXT: addi
193# NoOpt-NEXT: addis 3, 2, 0
194# NoOpt-NEXT: lxv 3, 32656(3)
195# NoOpt-NEXT: addis 3, 2, 0
196# NoOpt-NEXT: stxv 3, 32672(3)
197# NoOpt-NEXT: blr
198
199 .global vec_ds
200 .p2align 4
201 .type vec_ds,@function
202vec_ds:
203.Lvec_ds_gep:
204 addis 2, 12, .TOC.-.Lvec_ds_gep@ha
205 addi 2, 2, .TOC.-.Lvec_ds_gep@l
206.Lvec_ds_lep:
207 .localentry vec_ds, .Lvec_dq_lep-.Lvec_dq_gep
208 addis 3, 2, vecLd@toc@ha
209 lxsd 3, vecLd@toc@l(3)
210 addis 3, 2, vecSt@toc@ha
211 stxsd 3, vecSt@toc@l(3)
212 addis 3, 2, vecLd@toc@ha
213 lxssp 3, vecLd@toc@l(3)
214 addis 3, 2, vecSt@toc@ha
215 stxssp 3, vecSt@toc@l(3)
216 blr
217# Dis-LABEL: vec_ds
218# Dis-NEXT: addis
219# Dis-NEXT: addi
220# Dis-NEXT: nop
221# Dis-NEXT: lxsd 3, 32656(2)
222# Dis-NEXT: nop
223# Dis-NEXT: stxsd 3, 32672(2)
224# Dis-NEXT: nop
225# Dis-NEXT: lxssp 3, 32656(2)
226# Dis-NEXT: nop
227# Dis-NEXT: stxssp 3, 32672(2)
228# Dis-NEXT: blr
229
230# NoOpt-LABEL: vec_ds
231# NoOpt-NEXT: addis
232# NoOpt-NEXT: addi
233# NoOpt-NEXT: addis 3, 2, 0
234# NoOpt-NEXT: lxsd 3, 32656(3)
235# NoOpt-NEXT: addis 3, 2, 0
236# NoOpt-NEXT: stxsd 3, 32672(3)
237# NoOpt-NEXT: addis 3, 2, 0
238# NoOpt-NEXT: lxssp 3, 32656(3)
239# NoOpt-NEXT: addis 3, 2, 0
240# NoOpt-NEXT: stxssp 3, 32672(3)
241# NoOpt-NEXT: blr
242
243
244 .global byteLd
245 .lcomm byteLd, 1, 1
246
247 .global byteSt
248 .lcomm byteSt, 1, 1
249
250 .global halfLd
251 .lcomm halfLd, 2, 2
252
253 .global halfSt
254 .lcomm halfSt, 2, 2
255
256 .global wordLd
257 .lcomm wordLd, 4, 4
258
259 .global wordSt
260 .lcomm wordSt, 4, 4
261
262 .global dwordLd
263 .lcomm dwordLd, 8, 8
264
265 .global dwordSt
266 .lcomm dwordSt, 8, 8
267
268 .global vecLd
269 .lcomm vecLd, 16, 16
270
271 .global vecSt
272 .lcomm vecSt, 16, 16
deps/lld/test/ELF/ppc64-toc-rel.s+11-19
...@@ -1,13 +1,15 @@...@@ -1,13 +1,15 @@
1# REQUIRES: ppc1# REQUIRES: ppc
22
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS %s4# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-LE %s
5# RUN: ld.lld %t.o -o %t25# RUN: ld.lld %t.o -o %t2
6# RUN: llvm-objdump -D %t2 | FileCheck %s6# RUN: llvm-objdump -D %t2 | FileCheck %s
7# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %s
78
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
9# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s10# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
10# RUN: ld.lld %t.o -o %t211# RUN: ld.lld %t.o -o %t2
12# RUN: llvm-objdump -D %t2 | FileCheck %s
11# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s13# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
1214
13# Make sure we calculate the offset correctly for a toc-relative access to a15# Make sure we calculate the offset correctly for a toc-relative access to a
...@@ -45,15 +47,15 @@ _start:...@@ -45,15 +47,15 @@ _start:
4547
46# Verify the relocations that get emitted for the global variable are the48# Verify the relocations that get emitted for the global variable are the
47# expected ones.49# expected ones.
48# RELOCS: Relocations [50# RELOCS-LE: Relocations [
49# RELOCS-NEXT: .rela.text {51# RELOCS-LE-NEXT: .rela.text {
50# RELOCS: 0x8 R_PPC64_TOC16_HA global_a 0x052# RELOCS-LE: 0x8 R_PPC64_TOC16_HA global_a 0x0
51# RELOCS: 0xC R_PPC64_TOC16_LO global_a 0x053# RELOCS-LE: 0xC R_PPC64_TOC16_LO global_a 0x0
5254
53# RELOCS-BE: Relocations [55# RELOCS-BE: Relocations [
54# RELOCS-BE-NEXT: .rela.text {56# RELOCS-BE-NEXT: .rela.text {
55# RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x057# RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x0
56# RELOCS-NE: 0xE R_PPC64_TOC16_LO global_a 0x058# RELOCS-BE: 0xE R_PPC64_TOC16_LO global_a 0x0
5759
58# Want to check _start for the values used to build the offset from the TOC base60# Want to check _start for the values used to build the offset from the TOC base
59# to global_a. The .TOC. symbol is expected at address 0x10030000, and the61# to global_a. The .TOC. symbol is expected at address 0x10030000, and the
...@@ -70,19 +72,9 @@ _start:...@@ -70,19 +72,9 @@ _start:
70# CHECK-NEXT: global_a:72# CHECK-NEXT: global_a:
71# CHECK-NEXT: 10020000: {{.*}}73# CHECK-NEXT: 10020000: {{.*}}
7274
73# CHECK: Disassembly of section .got:75# CHECK-LE: Disassembly of section .got:
74# CHECK-NEXT: .got:76# CHECK-LE-NEXT: .got:
75# CHECK-NEXT: 10030000: 00 80 03 1077# CHECK-LE-NEXT: 10030000: 00 80 03 10
76
77
78# CHECK-BE: Disassembly of section .text:
79# CHECK-BE-NEXT: _start:
80# CHECK-BE: 10010008: {{.*}} addis 3, 2, -1
81# CHECK-BE-NEXT: 1001000c: {{.*}} addi 3, 3, -32768
82
83# CHECK-BE: Disassembly of section .data:
84# CHECK-BE-NEXT: global_a:
85# CHECK-BE-NEXT: 10020000: {{.*}}
8678
87# CHECK-BE: Disassembly of section .got:79# CHECK-BE: Disassembly of section .got:
88# CHECK-BE-NEXT: .got:80# CHECK-BE-NEXT: .got:
deps/lld/test/ELF/ppc64-toc-restore-recursive-call.s created+52
...@@ -0,0 +1,52 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
4# RUN: ld.lld -shared %t1.o -o %t
5# RUN: llvm-objdump -d -r %t | FileCheck %s
6
7# For a recursive call that is interposable the linker calls the plt-stub rather
8# then calling the function directly. Since the call is through a plt stub and
9# might be interposed with a different definition at runtime, a toc-restore is
10# required to follow the call.
11
12# The decision to use a plt-stub for the recursive call is not one I feel
13# strongly about either way. It was done because it matches what bfd and gold do
14# for recursive calls as well as keeps the logic for recursive calls consistent
15# with non-recursive calls.
16
17# CHECK-LABEL: __plt_recursive_func:
18# CHECK-NEXT: 10000:
19# CHECK-LABEL: recursive_func
20# CHECK-NEXT: 10014:
21# CHECK: 1003c: {{[0-9a-fA-F ]+}} bl .+67108804
22# CHECK-NEXT: ld 2, 24(1)
23
24 .abiversion 2
25 .section ".text"
26 .p2align 2
27 .global recursive_func
28 .type recursive_func, @function
29recursive_func:
30.Lrf_gep:
31 addis 2, 12, .TOC.-.Lrf_gep@ha
32 addi 2, 2, .TOC.-.Lrf_gep@l
33 .localentry recursive_func, .-recursive_func
34 cmpldi 3, 2
35 blt 0, .Lend
36
37 mflr 0
38 std 0, 16(1)
39 stdu 1, -32(1)
40 addi 5, 3, -1
41 mulld 4, 4, 3
42 mr 3, 5
43 bl recursive_func
44 nop
45 mr 4, 3
46 addi 1, 1, 32
47 ld 0, 16(1)
48 mtlr 0
49
50.Lend:
51 extsw 3, 4
52 blr
deps/lld/test/ELF/ppc64-toc-restore.s+1-1
...@@ -22,7 +22,7 @@ bar_local:...@@ -22,7 +22,7 @@ bar_local:
22 blr22 blr
2323
24# Calling external function foo in a shared object needs a nop.24# Calling external function foo in a shared object needs a nop.
25# Calling local function bar_local doe snot need a nop.25# Calling local function bar_local doe not need a nop.
26.global _start26.global _start
27_start:27_start:
28 bl foo28 bl foo
deps/lld/test/ELF/ppc64-tocopt-option.s created+14
...@@ -0,0 +1,14 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: not ld.lld %t --toc-optimize -o /dev/null 2>&1 | FileCheck %s
5
6# CHECK: error: --toc-optimize is only supported on the PowerPC64 target
7
8 .global __start
9 .type __start,@function
10
11 .text
12 .quad 0
13 __start:
14
deps/lld/test/ELF/ppc64_entry_point.s deleted-50
...@@ -1,50 +0,0 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-objdump -D %t2 | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
8# RUN: ld.lld %t -o %t2
9# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
10
11.text
12.abiversion 2
13.globl _start
14.p2align 4
15.type _start,@function
16
17_start:
18.Lfunc_begin0:
19.Lfunc_gep0:
20 lis 4, .Lfunc_gep0@ha
21 addi 4, 4, .Lfunc_gep0@l
22 # now r4 should contain the address of _start
23
24 lis 5, .TOC.-.Lfunc_gep0@ha
25 addi 5, 5, .TOC.-.Lfunc_gep0@l
26 # now r5 should contain the offset s.t. r4 + r5 = TOC base
27
28 # exit 55
29 li 0, 1
30 li 3, 55
31 sc
32.Lfunc_end0:
33 .size _start, .Lfunc_end0-.Lfunc_begin0
34
35// CHECK: 10010000: {{.*}} lis 4, 4097
36// CHECK-NEXT: 10010004: {{.*}} addi 4, 4, 0
37// CHECK-NEXT: 10010008: {{.*}} lis 5, 2
38// CHECK-NEXT: 1001000c: {{.*}} addi 5, 5, -32768
39// CHECK: Disassembly of section .got:
40// CHECK-NEXT: .got:
41// CHECK-NEXT: 10020000: 00 80 02 10
42
43// CHECK-BE: 10010000: {{.*}} lis 4, 4097
44// CHECK-BE-NEXT: 10010004: {{.*}} addi 4, 4, 0
45// CHECK-BE-NEXT: 10010008: {{.*}} lis 5, 2
46// CHECK-BE-NEXT: 1001000c: {{.*}} addi 5, 5, -32768
47// CHECK-BE: Disassembly of section .got:
48// CHECK-BE-NEXT: .got:
49// CHECK-BE-NEXT: 10020000: 00 00 00 00 {{.*}}
50// CHECK-BE-NEXT: 10020004: 10 02 80 00 {{.*}}
deps/lld/test/ELF/pr34660.s+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
4# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t4# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t
5# RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM5# RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM
6# RUN: llvm-readelf %t -t | FileCheck %s --check-prefix=SYM6# RUN: llvm-readelf %t --symbols | FileCheck %s --check-prefix=SYM
77
8# It would be much easier to understand/read this test if llvm-objdump would print8# It would be much easier to understand/read this test if llvm-objdump would print
9# the immediates in hex.9# the immediates in hex.
deps/lld/test/ELF/progname.s+1-1
...@@ -17,7 +17,7 @@...@@ -17,7 +17,7 @@
17// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so17// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
18// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s18// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
1919
20// CHECK: Name: __progname@20// CHECK: Name: __progname
21// CHECK-NEXT: Value: 0x20100021// CHECK-NEXT: Value: 0x201000
22// CHECK-NEXT: Size: 022// CHECK-NEXT: Size: 0
23// CHECK-NEXT: Binding: Global (0x1)23// CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/protected-shared.s+2-2
...@@ -32,7 +32,7 @@ bar:...@@ -32,7 +32,7 @@ bar:
3232
33// CHECK: DynamicSymbols [33// CHECK: DynamicSymbols [
34// CHECK-NEXT: Symbol {34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name: @35// CHECK-NEXT: Name:
36// CHECK-NEXT: Value: 0x036// CHECK-NEXT: Value: 0x0
37// CHECK-NEXT: Size: 037// CHECK-NEXT: Size: 0
38// CHECK-NEXT: Binding: Local (0x0)38// CHECK-NEXT: Binding: Local (0x0)
...@@ -41,7 +41,7 @@ bar:...@@ -41,7 +41,7 @@ bar:
41// CHECK-NEXT: Section: Undefined (0x0)41// CHECK-NEXT: Section: Undefined (0x0)
42// CHECK-NEXT: }42// CHECK-NEXT: }
43// CHECK-NEXT: Symbol {43// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: foo@44// CHECK-NEXT: Name: foo
45// CHECK-NEXT: Value: 0x045// CHECK-NEXT: Value: 0x0
46// CHECK-NEXT: Size: 046// CHECK-NEXT: Size: 0
47// CHECK-NEXT: Binding: Global47// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/push-state.s+3
...@@ -32,5 +32,8 @@...@@ -32,5 +32,8 @@
32// RUN: ld.lld -o %t.exe -L%t.dir -push-state -static -pop-state %t1.o -lfoo32// RUN: ld.lld -o %t.exe -L%t.dir -push-state -static -pop-state %t1.o -lfoo
33// RUN: not ld.lld -o %t.exe -L%t.dir -push-state -static %t1.o -lfoo33// RUN: not ld.lld -o %t.exe -L%t.dir -push-state -static %t1.o -lfoo
3434
35// RUN: not ld.lld -o %t.exe -pop-state %t.a %t1.o -M 2>&1 | FileCheck -check-prefix=ERR %s
36// ERR: error: unbalanced --push-state/--pop-state
37
35.globl _start38.globl _start
36_start:39_start:
deps/lld/test/ELF/relative-dynamic-reloc-ppc64.s+2-2
...@@ -32,7 +32,7 @@...@@ -32,7 +32,7 @@
3232
33// CHECK: DynamicSymbols [33// CHECK: DynamicSymbols [
34// CHECK-NEXT: Symbol {34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name: @35// CHECK-NEXT: Name:
36// CHECK-NEXT: Value: 0x036// CHECK-NEXT: Value: 0x0
37// CHECK-NEXT: Size: 037// CHECK-NEXT: Size: 0
38// CHECK-NEXT: Binding: Local38// CHECK-NEXT: Binding: Local
...@@ -41,7 +41,7 @@...@@ -41,7 +41,7 @@
41// CHECK-NEXT: Section: Undefined41// CHECK-NEXT: Section: Undefined
42// CHECK-NEXT: }42// CHECK-NEXT: }
43// CHECK-NEXT: Symbol {43// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: external@44// CHECK-NEXT: Name: external
45// CHECK-NEXT: Value: 0x045// CHECK-NEXT: Value: 0x0
46// CHECK-NEXT: Size: 046// CHECK-NEXT: Size: 0
47// CHECK-NEXT: Binding: Global47// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/relative-dynamic-reloc.s+2-2
...@@ -28,7 +28,7 @@...@@ -28,7 +28,7 @@
2828
29// CHECK: DynamicSymbols [29// CHECK: DynamicSymbols [
30// CHECK-NEXT: Symbol {30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name: @31// CHECK-NEXT: Name:
32// CHECK-NEXT: Value: 0x032// CHECK-NEXT: Value: 0x0
33// CHECK-NEXT: Size: 033// CHECK-NEXT: Size: 0
34// CHECK-NEXT: Binding: Local34// CHECK-NEXT: Binding: Local
...@@ -37,7 +37,7 @@...@@ -37,7 +37,7 @@
37// CHECK-NEXT: Section: Undefined37// CHECK-NEXT: Section: Undefined
38// CHECK-NEXT: }38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: external@40// CHECK-NEXT: Name: external
41// CHECK-NEXT: Value: 0x041// CHECK-NEXT: Value: 0x0
42// CHECK-NEXT: Size: 042// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Global43// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/relocatable-bss.s+1-1
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20# CHECK-NEXT: Version:20# CHECK-NEXT: Version:
21# CHECK-NEXT: Entry:21# CHECK-NEXT: Entry:
22# CHECK-NEXT: ProgramHeaderOffset:22# CHECK-NEXT: ProgramHeaderOffset:
23# CHECK-NEXT: SectionHeaderOffset: 0xD823# CHECK-NEXT: SectionHeaderOffset: 0xE8
24# CHECK-NEXT: Flags [24# CHECK-NEXT: Flags [
25# CHECK-NEXT: ]25# CHECK-NEXT: ]
26# CHECK-NEXT: HeaderSize:26# CHECK-NEXT: HeaderSize:
deps/lld/test/ELF/relocatable-comdat-multiple.s+2-2
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8# CHECK-NEXT: Group {8# CHECK-NEXT: Group {
9# CHECK-NEXT: Name: .group9# CHECK-NEXT: Name: .group
10# CHECK-NEXT: Index: 210# CHECK-NEXT: Index: 2
11# CHECK-NEXT: Link: 811# CHECK-NEXT: Link: 9
12# CHECK-NEXT: Info: 112# CHECK-NEXT: Info: 1
13# CHECK-NEXT: Type: COMDAT13# CHECK-NEXT: Type: COMDAT
14# CHECK-NEXT: Signature: aaa14# CHECK-NEXT: Signature: aaa
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20# CHECK-NEXT: Group {20# CHECK-NEXT: Group {
21# CHECK-NEXT: Name: .group21# CHECK-NEXT: Name: .group
22# CHECK-NEXT: Index: 522# CHECK-NEXT: Index: 5
23# CHECK-NEXT: Link: 823# CHECK-NEXT: Link: 9
24# CHECK-NEXT: Info: 624# CHECK-NEXT: Info: 6
25# CHECK-NEXT: Type: COMDAT25# CHECK-NEXT: Type: COMDAT
26# CHECK-NEXT: Signature: bbb26# CHECK-NEXT: Signature: bbb
deps/lld/test/ELF/relocatable-comdat.s+1-1
...@@ -30,7 +30,7 @@...@@ -30,7 +30,7 @@
30# CHECK-NEXT: Group {30# CHECK-NEXT: Group {
31# CHECK-NEXT: Name: .group31# CHECK-NEXT: Name: .group
32# CHECK-NEXT: Index: 232# CHECK-NEXT: Index: 2
33# CHECK-NEXT: Link: 533# CHECK-NEXT: Link: 6
34# CHECK-NEXT: Info: 1 34# CHECK-NEXT: Info: 1
35# CHECK-NEXT: Type: COMDAT35# CHECK-NEXT: Type: COMDAT
36# CHECK-NEXT: Signature: abc36# CHECK-NEXT: Signature: abc
deps/lld/test/ELF/relocatable-comdat2.s+2-2
...@@ -13,7 +13,7 @@...@@ -13,7 +13,7 @@
13# CHECK-NEXT: Group {13# CHECK-NEXT: Group {
14# CHECK-NEXT: Name: .group14# CHECK-NEXT: Name: .group
15# CHECK-NEXT: Index: 215# CHECK-NEXT: Index: 2
16# CHECK-NEXT: Link: 716# CHECK-NEXT: Link: 8
17# CHECK-NEXT: Info: 117# CHECK-NEXT: Info: 1
18# CHECK-NEXT: Type: COMDAT18# CHECK-NEXT: Type: COMDAT
19# CHECK-NEXT: Signature: bar19# CHECK-NEXT: Signature: bar
...@@ -24,7 +24,7 @@...@@ -24,7 +24,7 @@
24# CHECK-NEXT: Group {24# CHECK-NEXT: Group {
25# CHECK-NEXT: Name: .group25# CHECK-NEXT: Name: .group
26# CHECK-NEXT: Index: 426# CHECK-NEXT: Index: 4
27# CHECK-NEXT: Link: 727# CHECK-NEXT: Link: 8
28# CHECK-NEXT: Info: 228# CHECK-NEXT: Info: 2
29# CHECK-NEXT: Type: COMDAT29# CHECK-NEXT: Type: COMDAT
30# CHECK-NEXT: Signature: zed30# CHECK-NEXT: Signature: zed
deps/lld/test/ELF/relocatable-compressed-input.s+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7# RUN: ld.lld %t1 -o %t2 -r7# RUN: ld.lld %t1 -o %t2 -r
8# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s8# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
99
10## Check we decompress section and remove ".z" prefix specific for zlib-gnu compression.10## Check we uncompress section and remove ".z" prefix specific for zlib-gnu compression.
11# CHECK: Section {11# CHECK: Section {
12# CHECK: Index:12# CHECK: Index:
13# CHECK: Name: .debug_str13# CHECK: Name: .debug_str
deps/lld/test/ELF/relocatable-many-sections.s+10-8
...@@ -9,8 +9,8 @@...@@ -9,8 +9,8 @@
9## sections amount is greater than SHN_LORESERVE.9## sections amount is greater than SHN_LORESERVE.
10# RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR10# RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR
11# HDR: ElfHeader {11# HDR: ElfHeader {
12# HDR: SectionHeaderCount: 0 (65543)12# HDR: SectionHeaderCount: 0 (65544)
13# HDR-NEXT: StringTableSectionIndex: 65535 (65541)13# HDR-NEXT: StringTableSectionIndex: 65535 (65542)
1414
15## Check that:15## Check that:
16## 1) 65541 is the index of .shstrtab section.16## 1) 65541 is the index of .shstrtab section.
...@@ -18,13 +18,15 @@...@@ -18,13 +18,15 @@
18## 3) .symtab_shndxr entry size and alignment == 4.18## 3) .symtab_shndxr entry size and alignment == 4.
19## 4) .symtab_shndxr has size equal to19## 4) .symtab_shndxr has size equal to
20## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c20## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c
21
21# RUN: llvm-readelf -sections -symbols %t | FileCheck %s22# RUN: llvm-readelf -sections -symbols %t | FileCheck %s
22## [Nr] Name Type Address Off Size ES Flg Lk Inf Al23# [Nr] Name Type Address Off Size ES Flg Lk Inf Al
23# CHECK: [65538] .bar24# CHECK: [65539] .note.GNU-stack PROGBITS 0000000000000000 000040 000000 00 0 0 1
24# CHECK-NEXT: [65539] .symtab SYMTAB 0000000000000000 000040 180078 18 65542 65539 825# CHECK: [65540] .symtab SYMTAB 0000000000000000 000040 180078 18 65543 65539 8
25# CHECK-NEXT: [65540] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65539 0 426# CHECK: [65541] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65540 0 4
26# CHECK-NEXT: [65541] .shstrtab STRTAB 0000000000000000 1c00cc 0f0035 00 0 0 127# CHECK: [65542] .shstrtab STRTAB 0000000000000000 1c00cc 0f0045 00 0 0 1
27# CHECK-NEXT: [65542] .strtab STRTAB 0000000000000000 2b0101 00000c 0028# CHECK: [65543] .strtab STRTAB 0000000000000000 2b0111 00000c 00 0 0 1
29
28# 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE).30# 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE).
29# CHECK: GLOBAL DEFAULT 65538 foo31# CHECK: GLOBAL DEFAULT 65538 foo
3032
deps/lld/test/ELF/relocatable-rel-iplt.s created+56
...@@ -0,0 +1,56 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-- %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t2.o
4# RUN: llvm-readobj -t %t2.o | FileCheck %s
5
6// CHECK: Symbols [
7// CHECK-NEXT: Symbol {
8// CHECK-NEXT: Name: (0)
9// CHECK-NEXT: Value: 0x0
10// CHECK-NEXT: Size: 0
11// CHECK-NEXT: Binding: Local (0x0)
12// CHECK-NEXT: Type: None (0x0)
13// CHECK-NEXT: Other: 0
14// CHECK-NEXT: Section: Undefined (0x0)
15// CHECK-NEXT: }
16// CHECK-NEXT: Symbol {
17// CHECK-NEXT: Name: (0)
18// CHECK-NEXT: Value: 0x0
19// CHECK-NEXT: Size: 0
20// CHECK-NEXT: Binding: Local (0x0)
21// CHECK-NEXT: Type: Section (0x3)
22// CHECK-NEXT: Other: 0
23// CHECK-NEXT: Section: .text (0x1)
24// CHECK-NEXT: }
25// CHECK-NEXT: Symbol {
26// CHECK-NEXT: Name: __rel_iplt_end (1)
27// CHECK-NEXT: Value: 0x0
28// CHECK-NEXT: Size: 0
29// CHECK-NEXT: Binding: Weak (0x2)
30// CHECK-NEXT: Type: None (0x0)
31// CHECK-NEXT: Other [ (0x2)
32// CHECK-NEXT: STV_HIDDEN (0x2)
33// CHECK-NEXT: ]
34// CHECK-NEXT: Section: Undefined (0x0)
35// CHECK-NEXT: }
36// CHECK-NEXT: Symbol {
37// CHECK-NEXT: Name: __rel_iplt_start (16)
38// CHECK-NEXT: Value: 0x0
39// CHECK-NEXT: Size: 0
40// CHECK-NEXT: Binding: Weak (0x2)
41// CHECK-NEXT: Type: None (0x0)
42// CHECK-NEXT: Other [ (0x2)
43// CHECK-NEXT: STV_HIDDEN (0x2)
44// CHECK-NEXT: ]
45// CHECK-NEXT: Section: Undefined (0x0)
46// CHECK-NEXT: }
47// CHECK-NEXT: ]
48
49 movl __rel_iplt_start, %eax
50 movl __rel_iplt_end, %eax
51 ret
52
53 .hidden __rel_iplt_start
54 .hidden __rel_iplt_end
55 .weak __rel_iplt_start
56 .weak __rel_iplt_end
deps/lld/test/ELF/relocatable.s+14-2
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o
5# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t5# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
7# RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=SECTION %s
7# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s8# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
89
9## Test --relocatable alias10## Test --relocatable alias
...@@ -37,8 +38,8 @@...@@ -37,8 +38,8 @@
37# CHECK-NEXT: ProgramHeaderEntrySize: 038# CHECK-NEXT: ProgramHeaderEntrySize: 0
38# CHECK-NEXT: ProgramHeaderCount: 039# CHECK-NEXT: ProgramHeaderCount: 0
39# CHECK-NEXT: SectionHeaderEntrySize: 6440# CHECK-NEXT: SectionHeaderEntrySize: 64
40# CHECK-NEXT: SectionHeaderCount: 741# CHECK-NEXT: SectionHeaderCount: 8
41# CHECK-NEXT: StringTableSectionIndex: 542# CHECK-NEXT: StringTableSectionIndex: 6
42# CHECK-NEXT: }43# CHECK-NEXT: }
4344
44# CHECK: Relocations [45# CHECK: Relocations [
...@@ -51,6 +52,17 @@...@@ -51,6 +52,17 @@
51# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x052# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0
52# CHECK-NEXT: }53# CHECK-NEXT: }
5354
55# SECTION: Sections:
56# SECTION: Idx Name Size Address Type
57# SECTION: 0 00000000 0000000000000000
58# SECTION: 1 .text 00000056 0000000000000000 TEXT
59# SECTION: 2 .rela.text 00000090 0000000000000000
60# SECTION: 3 .bss 00000018 0000000000000000 BSS
61# SECTION: 4 .note.GNU-stack 00000000 0000000000000000
62# SECTION: 5 .symtab 00000168 0000000000000000
63# SECTION: 6 .shstrtab 00000041 0000000000000000
64# SECTION: 7 .strtab 0000002d 0000000000000000
65
54# CHECKTEXT: Disassembly of section .text:66# CHECKTEXT: Disassembly of section .text:
55# CHECKTEXT-NEXT: main:67# CHECKTEXT-NEXT: main:
56# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 068# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
deps/lld/test/ELF/relocation-b-aarch64.test+2-2
...@@ -9,9 +9,9 @@...@@ -9,9 +9,9 @@
99
10# CHECK: Disassembly of section .text:10# CHECK: Disassembly of section .text:
11# CHECK-NEXT: foo:11# CHECK-NEXT: foo:
12# CHECK-NEXT: 20000: 01 00 00 14 b #412# CHECK-NEXT: 210000: 01 00 00 14 b #4
13# CHECK: bar:13# CHECK: bar:
14# CHECK-NEXT: 20004: ff ff ff 17 b #-414# CHECK-NEXT: 210004: ff ff ff 17 b #-4
1515
16!ELF16!ELF
17FileHeader:17FileHeader:
deps/lld/test/ELF/relocation-before-merge-start.s created+9
...@@ -0,0 +1,9 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
4// CHECK: relocation-before-merge-start.s.tmp.o:(.foo): offset is outside the section
5
6.data
7.long .foo - 1
8.section .foo,"aM",@progbits,4
9.quad 0
deps/lld/test/ELF/relocation-common.s+6-6
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: x861# REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t -o %tout3# RUN: ld.lld %t.o -o %t
4// RUN: llvm-objdump -t -d %tout | FileCheck %s4# RUN: llvm-objdump -t -d %t | FileCheck %s
55
6.global _start6.global _start
7_start:7_start:
...@@ -10,5 +10,5 @@ _start:...@@ -10,5 +10,5 @@ _start:
10.global sym110.global sym1
11.comm sym1,4,411.comm sym1,4,4
1212
13// CHECK: 201000: {{.*}} movl $1, 4086(%rip)13# CHECK: 201000: {{.*}} movl $1, 4086(%rip)
14// CHECK: 0000000000202000 g .bss 00000004 sym114# CHECK: 0000000000202000 g O .bss 00000004 sym1
deps/lld/test/ELF/relocation-copy-i686.s+7-7
...@@ -21,7 +21,7 @@ movl $9, z...@@ -21,7 +21,7 @@ movl $9, z
21// CHECK-NEXT: SHF_ALLOC21// CHECK-NEXT: SHF_ALLOC
22// CHECK-NEXT: SHF_WRITE22// CHECK-NEXT: SHF_WRITE
23// CHECK-NEXT: ]23// CHECK-NEXT: ]
24// CHECK-NEXT: Address: 0x1300024// CHECK-NEXT: Address: 0x403000
25// CHECK-NEXT: Offset:25// CHECK-NEXT: Offset:
26// CHECK-NEXT: Size: 2426// CHECK-NEXT: Size: 24
27// CHECK-NEXT: Link: 027// CHECK-NEXT: Link: 0
...@@ -52,12 +52,12 @@ movl $9, z...@@ -52,12 +52,12 @@ movl $9, z
52// CHECK-NEXT: }52// CHECK-NEXT: }
53// CHECK-NEXT: ]53// CHECK-NEXT: ]
5454
55// 77824 = 0x1300055// 4206592 = 0x403000
56// 16 is alignment here56// 16 is alignment here
57// 77840 = 0x13000 + 1657// 4206608 = 0x403000 + 16
58// 77844 = 0x13000 + 16 + 458// 4206612 = 0x403000 + 16 + 4
59// CODE: Disassembly of section .text:59// CODE: Disassembly of section .text:
60// CODE-NEXT: main:60// CODE-NEXT: main:
61// CODE-NEXT: 11000: c7 05 00 30 01 00 05 00 00 00 movl $5, 7782461// CODE-NEXT: 401000: c7 05 00 30 40 00 05 00 00 00 movl $5, 4206592
62// CODE-NEXT: 1100a: c7 05 10 30 01 00 07 00 00 00 movl $7, 7784062// CODE-NEXT: 40100a: c7 05 10 30 40 00 07 00 00 00 movl $7, 4206608
63// CODE-NEXT: 11014: c7 05 14 30 01 00 09 00 00 00 movl $9, 7784463// CODE-NEXT: 401014: c7 05 14 30 40 00 09 00 00 00 movl $9, 4206612
deps/lld/test/ELF/relocation-i686.s+15-15
...@@ -27,14 +27,14 @@ R_386_PC32_2:...@@ -27,14 +27,14 @@ R_386_PC32_2:
2727
28// CHECK: Disassembly of section .R_386_32:28// CHECK: Disassembly of section .R_386_32:
29// CHECK-NEXT: R_386_32:29// CHECK-NEXT: R_386_32:
30// CHECK-NEXT: 11000: {{.*}} movl $69633, %edx30// CHECK-NEXT: 401000: {{.*}} movl $4198401, %edx
3131
32// CHECK: Disassembly of section .R_386_PC32:32// CHECK: Disassembly of section .R_386_PC32:
33// CHECK-NEXT: R_386_PC32:33// CHECK-NEXT: R_386_PC32:
34// CHECK-NEXT: 11005: e8 04 00 00 00 calll 434// CHECK-NEXT: 401005: e8 04 00 00 00 calll 4
3535
36// CHECK: R_386_PC32_2:36// CHECK: R_386_PC32_2:
37// CHECK-NEXT: 1100e: 90 nop37// CHECK-NEXT: 40100e: 90 nop
3838
39// Create a .got39// Create a .got
40movl bar@GOT, %eax40movl bar@GOT, %eax
...@@ -45,7 +45,7 @@ movl bar@GOT, %eax...@@ -45,7 +45,7 @@ movl bar@GOT, %eax
45// ADDR-NEXT: SHF_ALLOC45// ADDR-NEXT: SHF_ALLOC
46// ADDR-NEXT: SHF_EXECINSTR46// ADDR-NEXT: SHF_EXECINSTR
47// ADDR-NEXT: ]47// ADDR-NEXT: ]
48// ADDR-NEXT: Address: 0x1104048// ADDR-NEXT: Address: 0x401040
49// ADDR-NEXT: Offset: 0x104049// ADDR-NEXT: Offset: 0x1040
50// ADDR-NEXT: Size: 3250// ADDR-NEXT: Size: 32
5151
...@@ -55,7 +55,7 @@ movl bar@GOT, %eax...@@ -55,7 +55,7 @@ movl bar@GOT, %eax
55// ADDR-NEXT: SHF_ALLOC55// ADDR-NEXT: SHF_ALLOC
56// ADDR-NEXT: SHF_WRITE56// ADDR-NEXT: SHF_WRITE
57// ADDR-NEXT: ]57// ADDR-NEXT: ]
58// ADDR-NEXT: Address: 0x1307858// ADDR-NEXT: Address: 0x403078
59// ADDR-NEXT: Offset:59// ADDR-NEXT: Offset:
60// ADDR-NEXT: Size: 860// ADDR-NEXT: Size: 8
6161
...@@ -63,18 +63,18 @@ movl bar@GOT, %eax...@@ -63,18 +63,18 @@ movl bar@GOT, %eax
63R_386_GOTPC:63R_386_GOTPC:
64 movl $_GLOBAL_OFFSET_TABLE_, %eax64 movl $_GLOBAL_OFFSET_TABLE_, %eax
6565
66// 0x12078 + 8 - 0x11014 = 420466// 0x402078 + 8 - 0x401014 = 4204
6767
68// CHECK: Disassembly of section .R_386_GOTPC:68// CHECK: Disassembly of section .R_386_GOTPC:
69// CHECK-NEXT: R_386_GOTPC:69// CHECK-NEXT: R_386_GOTPC:
70// CHECK-NEXT: 11014: {{.*}} movl $8300, %eax70// CHECK-NEXT: 401014: {{.*}} movl $8300, %eax
7171
72.section .dynamic_reloc, "ax",@progbits72.section .dynamic_reloc, "ax",@progbits
73 call bar73 call bar
74// addr(.plt) + 16 - (0x11019 + 5) = 5074// addr(.plt) + 16 - (0x401019 + 5) = 50
75// CHECK: Disassembly of section .dynamic_reloc:75// CHECK: Disassembly of section .dynamic_reloc:
76// CHECK-NEXT: .dynamic_reloc:76// CHECK-NEXT: .dynamic_reloc:
77// CHECK-NEXT: 11019: e8 32 00 00 00 calll 5077// CHECK-NEXT: 401019: e8 32 00 00 00 calll 50
7878
79.section .R_386_GOT32,"ax",@progbits79.section .R_386_GOT32,"ax",@progbits
80.global R_386_GOT3280.global R_386_GOT32
...@@ -84,13 +84,13 @@ R_386_GOT32:...@@ -84,13 +84,13 @@ R_386_GOT32:
84 movl bar+8@GOT, %eax84 movl bar+8@GOT, %eax
85 movl zed+4@GOT, %eax85 movl zed+4@GOT, %eax
8686
87// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)87// 4294967288 = 0xFFFFFFF8 = got[0](0x402070) - .got(0x402070) - sizeof(.got)(8)
88// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)88// 4294967292 = 0xFFFFFFFC = got[1](0x402074) - .got(0x402070) - sizeof(.got)(8)
89// 0xFFFFFFF8 + 8 = 089// 0xFFFFFFF8 + 8 = 0
90// 0xFFFFFFFC + 4 = 090// 0xFFFFFFFC + 4 = 0
91// CHECK: Disassembly of section .R_386_GOT32:91// CHECK: Disassembly of section .R_386_GOT32:
92// CHECK-NEXT: R_386_GOT32:92// CHECK-NEXT: R_386_GOT32:
93// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax93// CHECK-NEXT: 40101e: a1 f8 ff ff ff movl 4294967288, %eax
94// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax94// CHECK-NEXT: 401023: a1 fc ff ff ff movl 4294967292, %eax
95// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax95// CHECK-NEXT: 401028: a1 00 00 00 00 movl 0, %eax
96// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax96// CHECK-NEXT: 40102d: a1 00 00 00 00 movl 0, %eax
deps/lld/test/ELF/relocation-past-merge-end.s+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s3// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
4// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): entry is past the end of the section4// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): offset is outside the section
55
6.data6.data
7.long .foo + 107.long .foo + 10
deps/lld/test/ELF/relocation-size-shared.s+1-14
...@@ -28,20 +28,7 @@...@@ -28,20 +28,7 @@
28// DISASM-NEXT: 20100c: 00 0028// DISASM-NEXT: 20100c: 00 00
29// DISASM-NEXT: 20100e: 00 0029// DISASM-NEXT: 20100e: 00 00
30// DISASM-NEXT: 201010: 1b 0030// DISASM-NEXT: 201010: 1b 00
31// DISASM-NEXT: 201012: 00 0031// DISASM-NEXT: ...
32// DISASM-NEXT: 201014: 00 00
33// DISASM-NEXT: 201016: 00 00
34// DISASM-NEXT: 201018: 00 00
35// DISASM-NEXT: 20101a: 00 00
36// DISASM-NEXT: 20101c: 00 00
37// DISASM-NEXT: 20101e: 00 00
38// DISASM-NEXT: 201020: 00 00
39// DISASM-NEXT: 201022: 00 00
40// DISASM-NEXT: 201024: 00 00
41// DISASM-NEXT: 201026: 00 00
42// DISASM-NEXT: 201028: 00 00
43// DISASM-NEXT: 20102a: 00 00
44// DISASM-NEXT: 20102c: 00 00
45// DISASM-NEXT: 20102e: 00 0032// DISASM-NEXT: 20102e: 00 00
46// DISASM: _start:33// DISASM: _start:
47// DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax34// DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax
deps/lld/test/ELF/relocation-size.s+1-12
...@@ -57,18 +57,7 @@...@@ -57,18 +57,7 @@
5757
58// DISASMSHARED: Disassembly of section test:58// DISASMSHARED: Disassembly of section test:
59// DISASMSHARED-NEXT: _data:59// DISASMSHARED-NEXT: _data:
60// DISASMSHARED-NEXT: 1000: 00 0060// DISASMSHARED-NEXT: ...
61// DISASMSHARED-NEXT: 1002: 00 00
62// DISASMSHARED-NEXT: 1004: 00 00
63// DISASMSHARED-NEXT: 1006: 00 00
64// DISASMSHARED-NEXT: 1008: 00 00
65// DISASMSHARED-NEXT: 100a: 00 00
66// DISASMSHARED-NEXT: 100c: 00 00
67// DISASMSHARED-NEXT: 100e: 00 00
68// DISASMSHARED-NEXT: 1010: 00 00
69// DISASMSHARED-NEXT: 1012: 00 00
70// DISASMSHARED-NEXT: 1014: 00 00
71// DISASMSHARED-NEXT: 1016: 00 00
72// DISASMSHARED-NEXT: 1018: 19 0061// DISASMSHARED-NEXT: 1018: 19 00
73// DISASMSHARED-NEXT: 101a: 00 0062// DISASMSHARED-NEXT: 101a: 00 00
74// DISASMSHARED-NEXT: 101c: 00 0063// DISASMSHARED-NEXT: 101c: 00 00
deps/lld/test/ELF/reproduce-backslash.s+1-1
...@@ -6,4 +6,4 @@...@@ -6,4 +6,4 @@
6# RUN: ld.lld %T/foo\\.o --reproduce %T/repro.tar -o /dev/null6# RUN: ld.lld %T/foo\\.o --reproduce %T/repro.tar -o /dev/null
7# RUN: tar tf %T/repro.tar | FileCheck %s7# RUN: tar tf %T/repro.tar | FileCheck %s
88
9# CHECK: repro/{{.*}}/foo\\.o9# CHECK: repro/{{.*}}/foo\{{[\]?}}.o
deps/lld/test/ELF/retain-symbols-file.s+1-1
...@@ -11,7 +11,7 @@...@@ -11,7 +11,7 @@
1111
12# CHECK: DynamicSymbols [12# CHECK: DynamicSymbols [
13# CHECK-NEXT: Symbol {13# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Name: @14# CHECK-NEXT: Name:
15# CHECK-NEXT: Value:15# CHECK-NEXT: Value:
16# CHECK-NEXT: Size:16# CHECK-NEXT: Size:
17# CHECK-NEXT: Binding:17# CHECK-NEXT: Binding:
deps/lld/test/ELF/riscv-branch.test created+119
...@@ -0,0 +1,119 @@
1# .option norelax
2# .global _start
3# _start:
4# beq x0, x0, _start
5#
6# .section .reloc_max, "ax", @progbits
7# L1:
8# beq x0, x0, L1 + 0xffe
9#
10# .section .reloc_min, "ax", @progbits
11# L2:
12# beq x0, x0, L2 - 0x1000
13#
14# REQUIRES: riscv
15# RUN: yaml2obj %s -o %t.o
16# RUN: ld.lld %t.o -o %t
17# RUN: obj2yaml %t | FileCheck %s
18#
19# CHECK: - Name: .text
20# CHECK: Content: '63000000'
21# 11000: 00000063 beqz zero,11000 <_start>
22#
23# CHECK: - Name: .reloc_max
24# CHECK: Content: E30F007E
25# 11004: 7e000fe3 beqz zero,12002
26#
27# CHECK: - Name: .reloc_min
28# CHECK: Content: '63000080'
29# 11008: 80000063 beqz zero,10008
30
31--- !ELF
32FileHeader:
33 Class: ELFCLASS32
34 Data: ELFDATA2LSB
35 Type: ET_REL
36 Machine: EM_RISCV
37 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
38Sections:
39 - Name: .text
40 Type: SHT_PROGBITS
41 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
42 AddressAlign: 0x0000000000000002
43 Content: '63000000'
44 - Name: .rela.text
45 Type: SHT_RELA
46 Flags: [ SHF_INFO_LINK ]
47 Link: .symtab
48 AddressAlign: 0x0000000000000004
49 Info: .text
50 Relocations:
51 - Offset: 0x0000000000000000
52 Symbol: _start
53 Type: R_RISCV_BRANCH
54 - Name: .data
55 Type: SHT_PROGBITS
56 Flags: [ SHF_WRITE, SHF_ALLOC ]
57 AddressAlign: 0x0000000000000001
58 Content: ''
59 - Name: .bss
60 Type: SHT_NOBITS
61 Flags: [ SHF_WRITE, SHF_ALLOC ]
62 AddressAlign: 0x0000000000000001
63 - Name: .reloc_max
64 Type: SHT_PROGBITS
65 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
66 AddressAlign: 0x0000000000000001
67 Content: E30F007E
68 - Name: .rela.reloc_max
69 Type: SHT_RELA
70 Flags: [ SHF_INFO_LINK ]
71 Link: .symtab
72 AddressAlign: 0x0000000000000004
73 Info: .reloc_max
74 Relocations:
75 - Offset: 0x0000000000000000
76 Symbol: L1
77 Type: R_RISCV_BRANCH
78 Addend: 4094
79 - Name: .reloc_min
80 Type: SHT_PROGBITS
81 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
82 AddressAlign: 0x0000000000000001
83 Content: '63000080'
84 - Name: .rela.reloc_min
85 Type: SHT_RELA
86 Flags: [ SHF_INFO_LINK ]
87 Link: .symtab
88 AddressAlign: 0x0000000000000004
89 Info: .reloc_min
90 Relocations:
91 - Offset: 0x0000000000000000
92 Symbol: L2
93 Type: R_RISCV_BRANCH
94 Addend: -4096
95Symbols:
96 Local:
97 - Name: .text
98 Type: STT_SECTION
99 Section: .text
100 - Name: .data
101 Type: STT_SECTION
102 Section: .data
103 - Name: .bss
104 Type: STT_SECTION
105 Section: .bss
106 - Name: .reloc_max
107 Type: STT_SECTION
108 Section: .reloc_max
109 - Name: L1
110 Section: .reloc_max
111 - Name: .reloc_min
112 Type: STT_SECTION
113 Section: .reloc_min
114 - Name: L2
115 Section: .reloc_min
116 Global:
117 - Name: _start
118 Section: .text
119...
deps/lld/test/ELF/riscv-call.test created+95
...@@ -0,0 +1,95 @@
1# .option norelax
2# .global _start
3# _start:
4# call _start + 4
5#
6# .section .reloc_neg, "ax", @progbits
7# L1:
8# call L1 - 4
9#
10# REQUIRES: riscv
11# RUN: yaml2obj %s -o %t.o
12# RUN: ld.lld %t.o -o %t
13# RUN: obj2yaml %t | FileCheck %s
14#
15# CHECK: - Name: .text
16# CHECK: Content: '97000000E7804000'
17#
18# 11000: 00000097 auipc ra,0x0
19# 11004: 004080e7 jalr 4(ra)
20#
21# CHECK: - Name: .reloc_neg
22# CHECK: Content: 97000000E780C0FF
23#
24# 11008: 00000097 auipc ra,0x0
25# 1100c: ffc080e7 jalr -4(ra)
26
27--- !ELF
28FileHeader:
29 Class: ELFCLASS32
30 Data: ELFDATA2LSB
31 Type: ET_REL
32 Machine: EM_RISCV
33 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
34Sections:
35 - Name: .text
36 Type: SHT_PROGBITS
37 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
38 AddressAlign: 0x0000000000000002
39 Content: '97000000E7800000'
40 - Name: .rela.text
41 Type: SHT_RELA
42 Flags: [ SHF_INFO_LINK ]
43 Link: .symtab
44 AddressAlign: 0x0000000000000004
45 Info: .text
46 Relocations:
47 - Offset: 0x0000000000000000
48 Symbol: _start
49 Type: R_RISCV_CALL
50 Addend: 4
51 - Name: .data
52 Type: SHT_PROGBITS
53 Flags: [ SHF_WRITE, SHF_ALLOC ]
54 AddressAlign: 0x0000000000000001
55 Content: ''
56 - Name: .bss
57 Type: SHT_NOBITS
58 Flags: [ SHF_WRITE, SHF_ALLOC ]
59 AddressAlign: 0x0000000000000001
60 - Name: .reloc_neg
61 Type: SHT_PROGBITS
62 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
63 AddressAlign: 0x0000000000000001
64 Content: '97000000E7800000'
65 - Name: .rela.reloc_neg
66 Type: SHT_RELA
67 Flags: [ SHF_INFO_LINK ]
68 Link: .symtab
69 AddressAlign: 0x0000000000000004
70 Info: .reloc_neg
71 Relocations:
72 - Offset: 0x0000000000000000
73 Symbol: L1
74 Type: R_RISCV_CALL
75 Addend: -4
76Symbols:
77 Local:
78 - Name: .text
79 Type: STT_SECTION
80 Section: .text
81 - Name: .data
82 Type: STT_SECTION
83 Section: .data
84 - Name: .bss
85 Type: STT_SECTION
86 Section: .bss
87 - Name: .reloc_neg
88 Type: STT_SECTION
89 Section: .reloc_neg
90 - Name: L1
91 Section: .reloc_neg
92 Global:
93 - Name: _start
94 Section: .text
95...
deps/lld/test/ELF/riscv-hi20-lo12.test created+86
...@@ -0,0 +1,86 @@
1# .option norelax
2# .global _start
3#
4# .section .reloc_12345678, "ax", @progbits
5# _start:
6# foo = 0x12345678
7# lui a0, %hi(foo)
8# addi a0, a0, %lo(foo)
9# lw a0, %lo(foo)(a0)
10#
11# .section .reloc_fedcba98, "ax", @progbits
12# foo = 0xfedcba98
13# lui a0, %hi(foo)
14# addi a0, a0, %lo(foo)
15#
16# REQUIRES: riscv
17# RUN: yaml2obj %s -o %t.o
18# RUN: ld.lld %t.o -o %t
19# RUN: obj2yaml %t | FileCheck %s
20#
21# CHECK: - Name: .reloc_12345678
22# CHECK: Content: '375534121305856703258567'
23# 11000: 12345537 lui a0,0x12345
24# 11004: 67850513 addi a0,a0,1656 # 12345678 <__global_pointer$+0x12332e78>
25# 11008: 67852503 lw a0,1656(a0)
26#
27# CHECK: - Name: .reloc_fedcba98
28# CHECK: Content: 37C5DCFE130585A9
29# 1100c: fedcc537 lui a0,0xfedcc
30# 11010: a9850513 addi a0,a0,-1384 # fedcba98 <__global_pointer$+0xfedb9298>
31
32--- !ELF
33FileHeader:
34 Class: ELFCLASS32
35 Data: ELFDATA2LSB
36 Type: ET_REL
37 Machine: EM_RISCV
38 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
39Sections:
40 - Name: .text
41 Type: SHT_PROGBITS
42 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
43 AddressAlign: 0x0000000000000002
44 Content: ''
45 - Name: .data
46 Type: SHT_PROGBITS
47 Flags: [ SHF_WRITE, SHF_ALLOC ]
48 AddressAlign: 0x0000000000000001
49 Content: ''
50 - Name: .bss
51 Type: SHT_NOBITS
52 Flags: [ SHF_WRITE, SHF_ALLOC ]
53 AddressAlign: 0x0000000000000001
54 - Name: .reloc_12345678
55 Type: SHT_PROGBITS
56 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
57 AddressAlign: 0x0000000000000001
58 Content: '375534121305856703258567'
59 - Name: .reloc_fedcba98
60 Type: SHT_PROGBITS
61 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
62 AddressAlign: 0x0000000000000001
63 Content: 37C5DCFE130585A9
64Symbols:
65 Local:
66 - Name: .text
67 Type: STT_SECTION
68 Section: .text
69 - Name: .data
70 Type: STT_SECTION
71 Section: .data
72 - Name: .bss
73 Type: STT_SECTION
74 Section: .bss
75 - Name: .reloc_12345678
76 Type: STT_SECTION
77 Section: .reloc_12345678
78 - Name: foo
79 Value: 0x00000000FEDCBA98
80 - Name: .reloc_fedcba98
81 Type: STT_SECTION
82 Section: .reloc_fedcba98
83 Global:
84 - Name: _start
85 Section: .reloc_12345678
86...
deps/lld/test/ELF/riscv-jal-error.test created+93
...@@ -0,0 +1,93 @@
1# .option norelax
2# .global _start
3#
4# _start:
5# L1:
6# jal x0, L1 + 0x100000
7# L2:
8# jal x0, L2 - 0x100002
9# L3:
10# jal x0, L3 + 1
11# L4:
12# c.jal L4 + 1
13#
14# REQUIRES: riscv
15# RUN: yaml2obj %s -o %t.o
16# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
17#
18# CHECK: {{.*}}(.text+0x0): relocation R_RISCV_JAL out of range
19# CHECK: {{.*}}(.text+0x4): relocation R_RISCV_JAL out of range
20# CHECK: {{.*}}(.text+0x8): improper alignment for relocation R_RISCV_JAL
21# CHECK: {{.*}}(.text+0xC): improper alignment for relocation R_RISCV_RVC_JUMP
22
23--- !ELF
24FileHeader:
25 Class: ELFCLASS32
26 Data: ELFDATA2LSB
27 Type: ET_REL
28 Machine: EM_RISCV
29 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
30Sections:
31 - Name: .text
32 Type: SHT_PROGBITS
33 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
34 AddressAlign: 0x0000000000000002
35 Content: 6F0000806FF0FF7F6F0000000120
36 - Name: .rela.text
37 Type: SHT_RELA
38 Flags: [ SHF_INFO_LINK ]
39 Link: .symtab
40 AddressAlign: 0x0000000000000004
41 Info: .text
42 Relocations:
43 - Offset: 0x0000000000000000
44 Symbol: L1
45 Type: R_RISCV_JAL
46 Addend: 1048576
47 - Offset: 0x0000000000000004
48 Symbol: L2
49 Type: R_RISCV_JAL
50 Addend: -1048578
51 - Offset: 0x0000000000000008
52 Symbol: L3
53 Type: R_RISCV_JAL
54 Addend: 1
55 - Offset: 0x000000000000000C
56 Symbol: L4
57 Type: R_RISCV_RVC_JUMP
58 Addend: 1
59 - Name: .data
60 Type: SHT_PROGBITS
61 Flags: [ SHF_WRITE, SHF_ALLOC ]
62 AddressAlign: 0x0000000000000001
63 Content: ''
64 - Name: .bss
65 Type: SHT_NOBITS
66 Flags: [ SHF_WRITE, SHF_ALLOC ]
67 AddressAlign: 0x0000000000000001
68Symbols:
69 Local:
70 - Name: .text
71 Type: STT_SECTION
72 Section: .text
73 - Name: .data
74 Type: STT_SECTION
75 Section: .data
76 - Name: .bss
77 Type: STT_SECTION
78 Section: .bss
79 - Name: L1
80 Section: .text
81 - Name: L2
82 Section: .text
83 Value: 0x0000000000000004
84 - Name: L3
85 Section: .text
86 Value: 0x0000000000000008
87 - Name: L4
88 Section: .text
89 Value: 0x000000000000000C
90 Global:
91 - Name: _start
92 Section: .text
93...
deps/lld/test/ELF/riscv-jal.test created+161
...@@ -0,0 +1,161 @@
1# .option norelax
2# .global _start
3#
4# .section .reloc_zero, "ax", @progbits
5# _start:
6# L1:
7# jal x0, L1
8# L2:
9# c.jal L2
10#
11# .section .reloc_max, "ax", @progbits
12# L3:
13# jal x0, L3 + 0xffffe
14# L4:
15# c.jal L4 + 0x7fe
16#
17# .section .reloc_min, "ax", @progbits
18# L5:
19# jal x0, L5 - 0x100000
20# L6:
21# c.jal L6 - 0x800
22#
23# REQUIRES: riscv
24# RUN: yaml2obj %s -o %t.o
25# RUN: ld.lld %t.o -o %t
26# RUN: obj2yaml %t | FileCheck %s
27#
28# CHECK: - Name: .reloc_zero
29# CHECK: Content: 6F0000000120
30# 11000: 0000006f j 11000
31# 11004: 2001 jal 11004
32#
33# CHECK: - Name: .reloc_max
34# CHECK: Content: 6FF0FF7FFD2F
35# 11006: 7ffff06f j 111004
36# 1100a: 2ffd jal 11808
37#
38# CHECK: - Name: .reloc_min
39# CHECK: Content: 6F0000800130
40# 1100c: 8000006f j fff1100c
41# 11010: 3001 jal 10810
42
43--- !ELF
44FileHeader:
45 Class: ELFCLASS32
46 Data: ELFDATA2LSB
47 Type: ET_REL
48 Machine: EM_RISCV
49 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
50Sections:
51 - Name: .text
52 Type: SHT_PROGBITS
53 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
54 AddressAlign: 0x0000000000000002
55 Content: ''
56 - Name: .data
57 Type: SHT_PROGBITS
58 Flags: [ SHF_WRITE, SHF_ALLOC ]
59 AddressAlign: 0x0000000000000001
60 Content: ''
61 - Name: .bss
62 Type: SHT_NOBITS
63 Flags: [ SHF_WRITE, SHF_ALLOC ]
64 AddressAlign: 0x0000000000000001
65 - Name: .reloc_zero
66 Type: SHT_PROGBITS
67 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
68 AddressAlign: 0x0000000000000001
69 Content: 6F0000000120
70 - Name: .rela.reloc_zero
71 Type: SHT_RELA
72 Flags: [ SHF_INFO_LINK ]
73 Link: .symtab
74 AddressAlign: 0x0000000000000004
75 Info: .reloc_zero
76 Relocations:
77 - Offset: 0x0000000000000000
78 Symbol: L1
79 Type: R_RISCV_JAL
80 - Offset: 0x0000000000000004
81 Symbol: L2
82 Type: R_RISCV_RVC_JUMP
83 - Name: .reloc_max
84 Type: SHT_PROGBITS
85 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
86 AddressAlign: 0x0000000000000001
87 Content: 6FF0FF7FFD2F
88 - Name: .rela.reloc_max
89 Type: SHT_RELA
90 Flags: [ SHF_INFO_LINK ]
91 Link: .symtab
92 AddressAlign: 0x0000000000000004
93 Info: .reloc_max
94 Relocations:
95 - Offset: 0x0000000000000000
96 Symbol: L3
97 Type: R_RISCV_JAL
98 Addend: 1048574
99 - Offset: 0x0000000000000004
100 Symbol: L4
101 Type: R_RISCV_RVC_JUMP
102 Addend: 2046
103 - Name: .reloc_min
104 Type: SHT_PROGBITS
105 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
106 AddressAlign: 0x0000000000000001
107 Content: 6F0000800130
108 - Name: .rela.reloc_min
109 Type: SHT_RELA
110 Flags: [ SHF_INFO_LINK ]
111 Link: .symtab
112 AddressAlign: 0x0000000000000004
113 Info: .reloc_min
114 Relocations:
115 - Offset: 0x0000000000000000
116 Symbol: L5
117 Type: R_RISCV_JAL
118 Addend: -1048576
119 - Offset: 0x0000000000000004
120 Symbol: L6
121 Type: R_RISCV_RVC_JUMP
122 Addend: -2048
123Symbols:
124 Local:
125 - Name: .text
126 Type: STT_SECTION
127 Section: .text
128 - Name: .data
129 Type: STT_SECTION
130 Section: .data
131 - Name: .bss
132 Type: STT_SECTION
133 Section: .bss
134 - Name: .reloc_zero
135 Type: STT_SECTION
136 Section: .reloc_zero
137 - Name: L1
138 Section: .reloc_zero
139 - Name: L2
140 Section: .reloc_zero
141 Value: 0x0000000000000004
142 - Name: .reloc_max
143 Type: STT_SECTION
144 Section: .reloc_max
145 - Name: L3
146 Section: .reloc_max
147 - Name: L4
148 Section: .reloc_max
149 Value: 0x0000000000000004
150 - Name: .reloc_min
151 Type: STT_SECTION
152 Section: .reloc_min
153 - Name: L5
154 Section: .reloc_min
155 - Name: L6
156 Section: .reloc_min
157 Value: 0x0000000000000004
158 Global:
159 - Name: _start
160 Section: .reloc_zero
161...
deps/lld/test/ELF/riscv-pcrel-hilo.test created+103
...@@ -0,0 +1,103 @@
1# .option norelax
2# .global _start
3#
4# _start:
5# auipc a0, %pcrel_hi(_start + 4)
6# addi a0, a0, %pcrel_lo(_start)
7#
8# .section .reloc_neg, "ax", @progbits
9# L1:
10# auipc a0, %pcrel_hi(L1 - 2)
11# addi a0, a0, %pcrel_lo(L1)
12#
13#
14# REQUIRES: riscv
15# RUN: yaml2obj %s -o %t.o
16# RUN: ld.lld %t.o -o %t
17# RUN: obj2yaml %t | FileCheck %s
18#
19# CHECK: - Name: .text
20# CHECK: Content: '1705000013054500'
21# 11000: 00000517 auipc a0,0x0
22# 11004: 00450513 addi a0,a0,4 # 11004 <_start+0x4>
23#
24# CHECK: - Name: .reloc_neg
25# CHECK: Content: 170500001305E5FF
26# 11008: 00000517 auipc a0,0x0
27# 1100c: ffe50513 addi a0,a0,-2 # 11006 <_start+0x6>
28
29--- !ELF
30FileHeader:
31 Class: ELFCLASS32
32 Data: ELFDATA2LSB
33 Type: ET_REL
34 Machine: EM_RISCV
35 Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SOFT ]
36Sections:
37 - Name: .text
38 Type: SHT_PROGBITS
39 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
40 AddressAlign: 0x0000000000000002
41 Content: '1705000013050500'
42 - Name: .rela.text
43 Type: SHT_RELA
44 Flags: [ SHF_INFO_LINK ]
45 Link: .symtab
46 AddressAlign: 0x0000000000000004
47 Info: .text
48 Relocations:
49 - Offset: 0x0000000000000000
50 Symbol: _start
51 Type: R_RISCV_PCREL_HI20
52 Addend: 4
53 - Offset: 0x0000000000000004
54 Symbol: _start
55 Type: R_RISCV_PCREL_LO12_I
56 - Name: .data
57 Type: SHT_PROGBITS
58 Flags: [ SHF_WRITE, SHF_ALLOC ]
59 AddressAlign: 0x0000000000000001
60 Content: ''
61 - Name: .bss
62 Type: SHT_NOBITS
63 Flags: [ SHF_WRITE, SHF_ALLOC ]
64 AddressAlign: 0x0000000000000001
65 - Name: .reloc_neg
66 Type: SHT_PROGBITS
67 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
68 AddressAlign: 0x0000000000000001
69 Content: '1705000013050500'
70 - Name: .rela.reloc_neg
71 Type: SHT_RELA
72 Flags: [ SHF_INFO_LINK ]
73 Link: .symtab
74 AddressAlign: 0x0000000000000004
75 Info: .reloc_neg
76 Relocations:
77 - Offset: 0x0000000000000000
78 Symbol: L1
79 Type: R_RISCV_PCREL_HI20
80 Addend: -2
81 - Offset: 0x0000000000000004
82 Symbol: L1
83 Type: R_RISCV_PCREL_LO12_I
84Symbols:
85 Local:
86 - Name: .text
87 Type: STT_SECTION
88 Section: .text
89 - Name: .data
90 Type: STT_SECTION
91 Section: .data
92 - Name: .bss
93 Type: STT_SECTION
94 Section: .bss
95 - Name: .reloc_neg
96 Type: STT_SECTION
97 Section: .reloc_neg
98 - Name: L1
99 Section: .reloc_neg
100 Global:
101 - Name: _start
102 Section: .text
103...
deps/lld/test/ELF/shared.s+10-10
...@@ -141,7 +141,7 @@...@@ -141,7 +141,7 @@
141// CHECK-NEXT: }141// CHECK-NEXT: }
142// CHECK-NEXT: Symbol {142// CHECK-NEXT: Symbol {
143// CHECK-NEXT: Name: _DYNAMIC143// CHECK-NEXT: Name: _DYNAMIC
144// CHECK-NEXT: Value: 0x12000144// CHECK-NEXT: Value: 0x402000
145// CHECK-NEXT: Size: 0145// CHECK-NEXT: Size: 0
146// CHECK-NEXT: Binding: Local146// CHECK-NEXT: Binding: Local
147// CHECK-NEXT: Type: None147// CHECK-NEXT: Type: None
...@@ -152,7 +152,7 @@...@@ -152,7 +152,7 @@
152// CHECK-NEXT: }152// CHECK-NEXT: }
153// CHECK-NEXT: Symbol {153// CHECK-NEXT: Symbol {
154// CHECK-NEXT: Name: _start154// CHECK-NEXT: Name: _start
155// CHECK-NEXT: Value: 0x11000155// CHECK-NEXT: Value: 0x401000
156// CHECK-NEXT: Size: 0156// CHECK-NEXT: Size: 0
157// CHECK-NEXT: Binding: Global157// CHECK-NEXT: Binding: Global
158// CHECK-NEXT: Type: None158// CHECK-NEXT: Type: None
...@@ -181,7 +181,7 @@...@@ -181,7 +181,7 @@
181181
182// CHECK: DynamicSymbols [182// CHECK: DynamicSymbols [
183// CHECK-NEXT: Symbol {183// CHECK-NEXT: Symbol {
184// CHECK-NEXT: Name: @184// CHECK-NEXT: Name:
185// CHECK-NEXT: Value: 0x0185// CHECK-NEXT: Value: 0x0
186// CHECK-NEXT: Size: 0186// CHECK-NEXT: Size: 0
187// CHECK-NEXT: Binding: Local187// CHECK-NEXT: Binding: Local
...@@ -190,8 +190,8 @@...@@ -190,8 +190,8 @@
190// CHECK-NEXT: Section: Undefined190// CHECK-NEXT: Section: Undefined
191// CHECK-NEXT: }191// CHECK-NEXT: }
192// CHECK-NEXT: Symbol {192// CHECK-NEXT: Symbol {
193// CHECK-NEXT: Name: _start@193// CHECK-NEXT: Name: _start
194// CHECK-NEXT: Value: 0x11000194// CHECK-NEXT: Value: 0x401000
195// CHECK-NEXT: Size: 0195// CHECK-NEXT: Size: 0
196// CHECK-NEXT: Binding: Global196// CHECK-NEXT: Binding: Global
197// CHECK-NEXT: Type: Non197// CHECK-NEXT: Type: Non
...@@ -199,7 +199,7 @@...@@ -199,7 +199,7 @@
199// CHECK-NEXT: Section: .text199// CHECK-NEXT: Section: .text
200// CHECK-NEXT: }200// CHECK-NEXT: }
201// CHECK-NEXT: Symbol {201// CHECK-NEXT: Symbol {
202// CHECK-NEXT: Name: bar@202// CHECK-NEXT: Name: bar
203// CHECK-NEXT: Value: 0x0203// CHECK-NEXT: Value: 0x0
204// CHECK-NEXT: Size: 0204// CHECK-NEXT: Size: 0
205// CHECK-NEXT: Binding: Global205// CHECK-NEXT: Binding: Global
...@@ -208,7 +208,7 @@...@@ -208,7 +208,7 @@
208// CHECK-NEXT: Section: Undefined208// CHECK-NEXT: Section: Undefined
209// CHECK-NEXT: }209// CHECK-NEXT: }
210// CHECK-NEXT: Symbol {210// CHECK-NEXT: Symbol {
211// CHECK-NEXT: Name: zed@211// CHECK-NEXT: Name: zed
212// CHECK-NEXT: Value: 0x0212// CHECK-NEXT: Value: 0x0
213// CHECK-NEXT: Size: 0213// CHECK-NEXT: Size: 0
214// CHECK-NEXT: Binding: Global214// CHECK-NEXT: Binding: Global
...@@ -220,7 +220,7 @@...@@ -220,7 +220,7 @@
220220
221// DONT_EXPORT: DynamicSymbols [221// DONT_EXPORT: DynamicSymbols [
222// DONT_EXPORT-NEXT: Symbol {222// DONT_EXPORT-NEXT: Symbol {
223// DONT_EXPORT-NEXT: Name: @223// DONT_EXPORT-NEXT: Name:
224// DONT_EXPORT-NEXT: Value: 0x0224// DONT_EXPORT-NEXT: Value: 0x0
225// DONT_EXPORT-NEXT: Size: 0225// DONT_EXPORT-NEXT: Size: 0
226// DONT_EXPORT-NEXT: Binding: Local (0x0)226// DONT_EXPORT-NEXT: Binding: Local (0x0)
...@@ -229,7 +229,7 @@...@@ -229,7 +229,7 @@
229// DONT_EXPORT-NEXT: Section: Undefined (0x0)229// DONT_EXPORT-NEXT: Section: Undefined (0x0)
230// DONT_EXPORT-NEXT: }230// DONT_EXPORT-NEXT: }
231// DONT_EXPORT-NEXT: Symbol {231// DONT_EXPORT-NEXT: Symbol {
232// DONT_EXPORT-NEXT: Name: bar@232// DONT_EXPORT-NEXT: Name: bar
233// DONT_EXPORT-NEXT: Value: 0x0233// DONT_EXPORT-NEXT: Value: 0x0
234// DONT_EXPORT-NEXT: Size: 0234// DONT_EXPORT-NEXT: Size: 0
235// DONT_EXPORT-NEXT: Binding: Global235// DONT_EXPORT-NEXT: Binding: Global
...@@ -238,7 +238,7 @@...@@ -238,7 +238,7 @@
238// DONT_EXPORT-NEXT: Section: Undefined238// DONT_EXPORT-NEXT: Section: Undefined
239// DONT_EXPORT-NEXT: }239// DONT_EXPORT-NEXT: }
240// DONT_EXPORT-NEXT: Symbol {240// DONT_EXPORT-NEXT: Symbol {
241// DONT_EXPORT-NEXT: Name: zed@241// DONT_EXPORT-NEXT: Name: zed
242// DONT_EXPORT-NEXT: Value: 0x0242// DONT_EXPORT-NEXT: Value: 0x0
243// DONT_EXPORT-NEXT: Size: 0243// DONT_EXPORT-NEXT: Size: 0
244// DONT_EXPORT-NEXT: Binding: Global244// DONT_EXPORT-NEXT: Binding: Global
deps/lld/test/ELF/sht-group-empty.test created+55
...@@ -0,0 +1,55 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld %t.o %t.o -o %t -r
3# RUN: llvm-readobj -s %t | FileCheck %s
4
5# CHECK: Name: .text.foo
6# CHECK: Name: .rela.text.foo
7
8--- !ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_X86_64
14Sections:
15 - Name: .group
16 Type: SHT_GROUP
17 Link: .symtab
18 Info: foo
19 Members:
20 - SectionOrType: GRP_COMDAT
21 - SectionOrType: .text.foo
22 - SectionOrType: .text.bar
23 - SectionOrType: .note
24 - Name: .note
25 Type: SHT_NOTE
26 Flags: [ SHF_GROUP ]
27 - Name: .text.foo
28 Type: SHT_PROGBITS
29 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
30 - Name: .text.bar
31 Type: SHT_PROGBITS
32 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
33 - Name: .rela.text.foo
34 Type: SHT_RELA
35 Flags: [ SHF_INFO_LINK, SHF_GROUP ]
36 Link: .symtab
37 Info: .text.foo
38 Relocations:
39 - Offset: 0x0000000000000000
40 Symbol: foo
41 Type: R_X86_64_64
42 - Name: .rela.text.bar
43 Type: SHT_RELA
44 Flags: [ SHF_INFO_LINK, SHF_GROUP ]
45 Link: .symtab
46 Info: .text.bar
47 Relocations:
48 - Offset: 0x0000000000000000
49 Symbol: bar
50 Type: R_X86_64_64
51Symbols:
52 Global:
53 - Name: foo
54 - Name: bar
55
deps/lld/test/ELF/sort-norosegment.s+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
4# RUN: ld.lld --hash-style=sysv -no-rosegment -o %t %t.o -shared4# RUN: ld.lld --hash-style=sysv -no-rosegment -o %t %t.o -shared
5# RUN: llvm-readelf -s %t | FileCheck %s5# RUN: llvm-readelf -S %t | FileCheck %s
66
7# CHECK: .dynsym {{.*}} A7# CHECK: .dynsym {{.*}} A
8# CHECK-NEXT: .hash {{.*}} A8# CHECK-NEXT: .hash {{.*}} A
deps/lld/test/ELF/static-error.s created+13
...@@ -0,0 +1,13 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared.s -o %t.o
3// RUN: ld.lld -shared -o %t.so %t.o
4
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
6// RUN: ld.lld -o /dev/null %t.o %t.so
7// RUN: not ld.lld -o /dev/null -static %t.o %t.so 2>&1 | FileCheck %s
8
9// CHECK: attempted static link of dynamic object
10
11.global _start
12_start:
13 nop
deps/lld/test/ELF/static-with-export-dynamic.s+1-1
...@@ -18,7 +18,7 @@...@@ -18,7 +18,7 @@
18// CHECK-NEXT: }18// CHECK-NEXT: }
19// CHECK-NEXT: Symbol {19// CHECK-NEXT: Symbol {
20// CHECK-NEXT: Name: _start20// CHECK-NEXT: Name: _start
21// CHECK-NEXT: Value: 0x1100021// CHECK-NEXT: Value: 0x401000
22// CHECK-NEXT: Size: 022// CHECK-NEXT: Size: 0
23// CHECK-NEXT: Binding: Global23// CHECK-NEXT: Binding: Global
24// CHECK-NEXT: Type: None24// CHECK-NEXT: Type: None
deps/lld/test/ELF/strip-debug.s+3-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1# REQUIRES: x861# REQUIRES: x86, zlib
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t2 --strip-debug3# RUN: ld.lld %t -o %t2 --strip-debug
4# RUN: llvm-readobj -sections %t2 | FileCheck %s4# RUN: llvm-readobj -sections %t2 | FileCheck %s
...@@ -12,3 +12,5 @@...@@ -12,3 +12,5 @@
1212
13.section .debug_Foo,"",@progbits13.section .debug_Foo,"",@progbits
14.section .zdebug_Bar,"",@progbits14.section .zdebug_Bar,"",@progbits
15.ascii "ZLIB"
16.quad 0
deps/lld/test/ELF/symbol-ordering-file-warnings.s+5-8
...@@ -19,11 +19,6 @@...@@ -19,11 +19,6 @@
19# RUN: --unresolved-symbols=ignore-all --no-warn-symbol-ordering --warn-symbol-ordering 2>&1 | \19# RUN: --unresolved-symbols=ignore-all --no-warn-symbol-ordering --warn-symbol-ordering 2>&1 | \
20# RUN: FileCheck %s --check-prefixes=WARN,MISSING20# RUN: FileCheck %s --check-prefixes=WARN,MISSING
2121
22# Check that a warning is emitted for undefined symbols.
23# RUN: echo "undefined" > %t-order-undef.txt
24# RUN: ld.lld %t1.o %t3.o -o %t --symbol-ordering-file %t-order-undef.txt \
25# RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,UNDEFINED
26
27# Check that a warning is emitted for imported shared symbols.22# Check that a warning is emitted for imported shared symbols.
28# RUN: echo "shared" > %t-order-shared.txt23# RUN: echo "shared" > %t-order-shared.txt
29# RUN: ld.lld %t1.o %t.so -o %t --symbol-ordering-file %t-order-shared.txt \24# RUN: ld.lld %t1.o %t.so -o %t --symbol-ordering-file %t-order-shared.txt \
...@@ -97,7 +92,7 @@...@@ -97,7 +92,7 @@
97# RUN: echo "_GLOBAL_OFFSET_TABLE_" >> %t-order-multi.txt92# RUN: echo "_GLOBAL_OFFSET_TABLE_" >> %t-order-multi.txt
98# RUN: echo "_start" >> %t-order-multi.txt93# RUN: echo "_start" >> %t-order-multi.txt
99# RUN: ld.lld %t1.o %t3.o %t.so -o %t --symbol-ordering-file %t-order-multi.txt --gc-sections -T %t.script \94# RUN: ld.lld %t1.o %t3.o %t.so -o %t --symbol-ordering-file %t-order-multi.txt --gc-sections -T %t.script \
100# RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2,SYNTHETIC95# RUN: 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2,SYNTHETIC
10196
102# WARN-NOT: warning:97# WARN-NOT: warning:
103# SAMESYM: warning: {{.*}}.txt: duplicate ordered symbol: _start98# SAMESYM: warning: {{.*}}.txt: duplicate ordered symbol: _start
...@@ -115,10 +110,12 @@...@@ -115,10 +110,12 @@
115# ABSOLUTE: warning: {{.*}}1.o: unable to order absolute symbol: absolute110# ABSOLUTE: warning: {{.*}}1.o: unable to order absolute symbol: absolute
116# WARN-NOT: warning:111# WARN-NOT: warning:
117# MISSING: warning: symbol ordering file: no such symbol: missing112# MISSING: warning: symbol ordering file: no such symbol: missing
113# WARN-NOT: warning:
118# MISSING2: warning: symbol ordering file: no such symbol: missing_sym114# MISSING2: warning: symbol ordering file: no such symbol: missing_sym
115# WARN-NOT: warning:
119# COMDAT: warning: {{.*}}1.o: unable to order discarded symbol: comdat116# COMDAT: warning: {{.*}}1.o: unable to order discarded symbol: comdat
120# MULTI: warning: {{.*}}3.o: unable to order undefined symbol: multi117# WARN-NOT: warning:
121# MULTI-NEXT: warning: {{.*}}2.o: unable to order absolute symbol: multi118# MULTI: warning: {{.*}}2.o: unable to order absolute symbol: multi
122# WARN-NOT: warning:119# WARN-NOT: warning:
123120
124absolute = 0x1234121absolute = 0x1234
deps/lld/test/ELF/textrel.s created+40
...@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu %s -o %t.o
3
4# Without --warn-text-ifunc, lld should run fine:
5# RUN: ld.lld -z notext %t.o -o %t2
6
7# With --warn-text-ifunc, lld should run with warnings:
8# RUN: ld.lld --warn-ifunc-textrel -z notext %t.o -o /dev/null 2>&1 | FileCheck %s
9# CHECK: using ifunc symbols when text relocations are allowed may produce
10# CHECK-SAME: a binary that will segfault, if the object file is linked with
11# CHECK-SAME: old version of glibc (glibc 2.28 and earlier). If this applies to
12# CHECK-SAME: you, consider recompiling the object files without -fPIC and
13# CHECK-SAME: without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to
14# CHECK-SAME: turn off this warning.
15# CHECK: >>> defined in {{.*}}
16# CHECK: >>> referenced by {{.*}}:(.text+0x8)
17
18# Without text relocations, lld should run fine:
19# RUN: ld.lld --fatal-warnings %t.o -o /dev/null
20
21.text
22.globl a_func_impl
23a_func_impl:
24 nop
25
26.globl selector
27.type selector,@function
28selector:
29 movl $a_func_impl, %eax
30 retq
31
32.globl a_func
33.type a_func,@gnu_indirect_function
34.set a_func, selector
35
36.globl _start
37.type _start,@function
38main:
39 callq a_func
40 retq
deps/lld/test/ELF/tls-i686.s+10-10
...@@ -32,16 +32,16 @@ _start:...@@ -32,16 +32,16 @@ _start:
3232
33// DIS: Disassembly of section test:33// DIS: Disassembly of section test:
34// DIS-NEXT: _start:34// DIS-NEXT: _start:
35// DIS-NEXT: 11000: ba 08 00 00 00 movl $8, %edx35// DIS-NEXT: 401000: ba 08 00 00 00 movl $8, %edx
36// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx36// DIS-NEXT: 401005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
37// DIS-NEXT: 1100c: 29 d0 subl %edx, %eax37// DIS-NEXT: 40100c: 29 d0 subl %edx, %eax
38// DIS-NEXT: 1100e: ba 04 00 00 00 movl $4, %edx38// DIS-NEXT: 40100e: ba 04 00 00 00 movl $4, %edx
39// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx39// DIS-NEXT: 401013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
40// DIS-NEXT: 1101a: 29 d0 subl %edx, %eax40// DIS-NEXT: 40101a: 29 d0 subl %edx, %eax
41// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx41// DIS-NEXT: 40101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
42// DIS-NEXT: 11023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax42// DIS-NEXT: 401023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
43// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx43// DIS-NEXT: 401029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
44// DIS-NEXT: 11030: 8d 81 77 00 00 00 leal 119(%ecx), %eax44// DIS-NEXT: 401030: 8d 81 77 00 00 00 leal 119(%ecx), %eax
4545
46// RELOC: Relocations [46// RELOC: Relocations [
47// RELOC-NEXT: ]47// RELOC-NEXT: ]
deps/lld/test/ELF/tls-in-archive.s+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o
3// RUN: rm -f %t.a
3// RUN: llvm-ar cru %t.a %t1.o4// RUN: llvm-ar cru %t.a %t1.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5// RUN: ld.lld %t2.o %t.a -o /dev/null6// RUN: ld.lld %t2.o %t.a -o /dev/null
deps/lld/test/ELF/tls-opt-gdiele-i686.s+10-10
...@@ -8,21 +8,21 @@...@@ -8,21 +8,21 @@
88
9// NORELOC: Relocations [9// NORELOC: Relocations [
10// NORELOC-NEXT: Section ({{.*}}) .rel.dyn {10// NORELOC-NEXT: Section ({{.*}}) .rel.dyn {
11// NORELOC-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x011// NORELOC-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
12// NORELOC-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x012// NORELOC-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
13// NORELOC-NEXT: }13// NORELOC-NEXT: }
14// NORELOC-NEXT: ]14// NORELOC-NEXT: ]
1515
16// DISASM: Disassembly of section .text:16// DISASM: Disassembly of section .text:
17// DISASM-NEXT: _start:17// DISASM-NEXT: _start:
18// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax18// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
19// DISASM-NEXT: 11006: 03 83 f8 ff ff ff addl -8(%ebx), %eax19// DISASM-NEXT: 401006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
20// DISASM-NEXT: 1100c: 65 a1 00 00 00 00 movl %gs:0, %eax20// DISASM-NEXT: 40100c: 65 a1 00 00 00 00 movl %gs:0, %eax
21// DISASM-NEXT: 11012: 03 83 fc ff ff ff addl -4(%ebx), %eax21// DISASM-NEXT: 401012: 03 83 fc ff ff ff addl -4(%ebx), %eax
22// DISASM-NEXT: 11018: 65 a1 00 00 00 00 movl %gs:0, %eax22// DISASM-NEXT: 401018: 65 a1 00 00 00 00 movl %gs:0, %eax
23// DISASM-NEXT: 1101e: 81 e8 08 00 00 00 subl $8, %eax23// DISASM-NEXT: 40101e: 81 e8 08 00 00 00 subl $8, %eax
24// DISASM-NEXT: 11024: 65 a1 00 00 00 00 movl %gs:0, %eax24// DISASM-NEXT: 401024: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 1102a: 81 e8 04 00 00 00 subl $4, %eax25// DISASM-NEXT: 40102a: 81 e8 04 00 00 00 subl $4, %eax
2626
27.type tlsexe1,@object27.type tlsexe1,@object
28.section .tbss,"awT",@nobits28.section .tbss,"awT",@nobits
deps/lld/test/ELF/tls-opt-i686.s+16-16
...@@ -10,25 +10,25 @@...@@ -10,25 +10,25 @@
10// DISASM: Disassembly of section .text:10// DISASM: Disassembly of section .text:
11// DISASM-NEXT: _start:11// DISASM-NEXT: _start:
12// LD -> LE:12// LD -> LE:
13// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax13// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
14// DISASM-NEXT: 11006: 90 nop14// DISASM-NEXT: 401006: 90 nop
15// DISASM-NEXT: 11007: 8d 74 26 00 leal (%esi,%eiz), %esi15// DISASM-NEXT: 401007: 8d 74 26 00 leal (%esi,%eiz), %esi
16// DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx16// DISASM-NEXT: 40100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
17// DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax17// DISASM-NEXT: 401011: 65 a1 00 00 00 00 movl %gs:0, %eax
18// DISASM-NEXT: 11017: 90 nop18// DISASM-NEXT: 401017: 90 nop
19// DISASM-NEXT: 11018: 8d 74 26 00 leal (%esi,%eiz), %esi19// DISASM-NEXT: 401018: 8d 74 26 00 leal (%esi,%eiz), %esi
20// DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx20// DISASM-NEXT: 40101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
21// IE -> LE:21// IE -> LE:
22// 4294967288 == 0xFFFFFFF822// 4294967288 == 0xFFFFFFF8
23// 4294967292 == 0xFFFFFFFC23// 4294967292 == 0xFFFFFFFC
24// DISASM-NEXT: 11022: 65 a1 00 00 00 00 movl %gs:0, %eax24// DISASM-NEXT: 401022: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 11028: c7 c0 f8 ff ff ff movl $4294967288, %eax25// DISASM-NEXT: 401028: c7 c0 f8 ff ff ff movl $4294967288, %eax
26// DISASM-NEXT: 1102e: 65 a1 00 00 00 00 movl %gs:0, %eax26// DISASM-NEXT: 40102e: 65 a1 00 00 00 00 movl %gs:0, %eax
27// DISASM-NEXT: 11034: c7 c0 fc ff ff ff movl $4294967292, %eax27// DISASM-NEXT: 401034: c7 c0 fc ff ff ff movl $4294967292, %eax
28// DISASM-NEXT: 1103a: 65 a1 00 00 00 00 movl %gs:0, %eax28// DISASM-NEXT: 40103a: 65 a1 00 00 00 00 movl %gs:0, %eax
29// DISASM-NEXT: 11040: 8d 80 f8 ff ff ff leal -8(%eax), %eax29// DISASM-NEXT: 401040: 8d 80 f8 ff ff ff leal -8(%eax), %eax
30// DISASM-NEXT: 11046: 65 a1 00 00 00 00 movl %gs:0, %eax30// DISASM-NEXT: 401046: 65 a1 00 00 00 00 movl %gs:0, %eax
31// DISASM-NEXT: 1104c: 8d 80 fc ff ff ff leal -4(%eax), %eax31// DISASM-NEXT: 40104c: 8d 80 fc ff ff ff leal -4(%eax), %eax
32.type tls0,@object32.type tls0,@object
33.section .tbss,"awT",@nobits33.section .tbss,"awT",@nobits
34.globl tls034.globl tls0
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s+21-21
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14// GOTREL-NEXT: SHF_ALLOC14// GOTREL-NEXT: SHF_ALLOC
15// GOTREL-NEXT: SHF_WRITE15// GOTREL-NEXT: SHF_WRITE
16// GOTREL-NEXT: ]16// GOTREL-NEXT: ]
17// GOTREL-NEXT: Address: 0x1205817// GOTREL-NEXT: Address: 0x402058
18// GOTREL-NEXT: Offset: 0x205818// GOTREL-NEXT: Offset: 0x2058
19// GOTREL-NEXT: Size: 819// GOTREL-NEXT: Size: 8
20// GOTREL-NEXT: Link: 020// GOTREL-NEXT: Link: 0
...@@ -24,8 +24,8 @@...@@ -24,8 +24,8 @@
24// GOTREL-NEXT: }24// GOTREL-NEXT: }
25// GOTREL: Relocations [25// GOTREL: Relocations [
26// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {26// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
27// GOTREL-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x027// GOTREL-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
28// GOTREL-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x028// GOTREL-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
29// GOTREL-NEXT: }29// GOTREL-NEXT: }
30// GOTREL-NEXT: ]30// GOTREL-NEXT: ]
3131
...@@ -33,24 +33,24 @@...@@ -33,24 +33,24 @@
33// DISASM-NEXT: _start:33// DISASM-NEXT: _start:
34// 4294967288 = 0xFFFFFFF834// 4294967288 = 0xFFFFFFF8
35// 4294967292 = 0xFFFFFFFC35// 4294967292 = 0xFFFFFFFC
36// 73808 = (.got)[0] = 0x1205836// 4202584 = (.got)[0] = 0x402058
37// 73812 = (.got)[1] = 0x1205C37// 4202588 = (.got)[1] = 0x40205C
38// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx38// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
39// DISASM-NEXT: 11006: 65 8b 01 movl %gs:(%ecx), %eax39// DISASM-NEXT: 401006: 65 8b 01 movl %gs:(%ecx), %eax
40// DISASM-NEXT: 11009: b8 f8 ff ff ff movl $4294967288, %eax40// DISASM-NEXT: 401009: b8 f8 ff ff ff movl $4294967288, %eax
41// DISASM-NEXT: 1100e: 65 8b 00 movl %gs:(%eax), %eax41// DISASM-NEXT: 40100e: 65 8b 00 movl %gs:(%eax), %eax
42// DISASM-NEXT: 11011: 81 c1 f8 ff ff ff addl $4294967288, %ecx42// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
43// DISASM-NEXT: 11017: 65 8b 01 movl %gs:(%ecx), %eax43// DISASM-NEXT: 401017: 65 8b 01 movl %gs:(%ecx), %eax
44// DISASM-NEXT: 1101a: c7 c1 fc ff ff ff movl $4294967292, %ecx44// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
45// DISASM-NEXT: 11020: 65 8b 01 movl %gs:(%ecx), %eax45// DISASM-NEXT: 401020: 65 8b 01 movl %gs:(%ecx), %eax
46// DISASM-NEXT: 11023: b8 fc ff ff ff movl $4294967292, %eax46// DISASM-NEXT: 401023: b8 fc ff ff ff movl $4294967292, %eax
47// DISASM-NEXT: 11028: 65 8b 00 movl %gs:(%eax), %eax47// DISASM-NEXT: 401028: 65 8b 00 movl %gs:(%eax), %eax
48// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx48// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
49// DISASM-NEXT: 11031: 65 8b 01 movl %gs:(%ecx), %eax49// DISASM-NEXT: 401031: 65 8b 01 movl %gs:(%ecx), %eax
50// DISASM-NEXT: 11034: 8b 0d 58 20 01 00 movl 73816, %ecx50// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx
51// DISASM-NEXT: 1103a: 65 8b 01 movl %gs:(%ecx), %eax51// DISASM-NEXT: 40103a: 65 8b 01 movl %gs:(%ecx), %eax
52// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx52// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx
53// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax53// DISASM-NEXT: 401043: 65 8b 01 movl %gs:(%ecx), %eax
5454
55.type tlslocal0,@object55.type tlslocal0,@object
56.section .tbss,"awT",@nobits56.section .tbss,"awT",@nobits
deps/lld/test/ELF/tls-opt-x86_64-noplt.s created+88
...@@ -0,0 +1,88 @@
1// REQUIRES: x86
2
3// Checks whether the TLS optimizations match the cases in Chapter 11 of
4// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
5
6// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
7// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
8// RUN: ld.lld -shared %tso.o -o %t.so
9// RUN: ld.lld %t.o %t.so -o %t1
10// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
11// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
12
13// RELOC: Relocations [
14// RELOC-NEXT: Section {{.*}} .rela.dyn {
15// RELOC-NEXT: 0x2020C0 R_X86_64_TPOFF64 tlsshared0 0x0
16// RELOC-NEXT: 0x2020C8 R_X86_64_TPOFF64 tlsshared1 0x0
17// RELOC-NEXT: }
18// RELOC-NEXT: ]
19
20// DISASM: _start:
21
22// Table 11.5: GD -> IE Code Transition (LP64)
23// DISASM-NEXT: 201000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
24// DISASM-NEXT: 201009: 48 03 05 b0 10 00 00 addq 4272(%rip), %rax
25// DISASM-NEXT: 201010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
26// DISASM-NEXT: 201019: 48 03 05 a8 10 00 00 addq 4264(%rip), %rax
27
28// Table 11.7: GD -> LE Code Transition (LP64)
29// DISASM-NEXT: 201020: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
30// DISASM-NEXT: 201029: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
31// DISASM-NEXT: 201030: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
32// DISASM-NEXT: 201039: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
33
34
35// Table 11.9: LD -> LE Code Transition (LP64)
36// DISASM-NEXT: 201040: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
37// DISASM-NEXT: 20104d: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
38
39.type tls0,@object
40.section .tbss,"awT",@nobits
41.globl tls0
42.align 4
43tls0:
44 .long 0
45 .size tls0, 4
46
47.type tls1,@object
48.globl tls1
49.align 4
50tls1:
51 .long 0
52 .size tls1, 4
53
54.section .text
55.globl _start
56_start:
57 // Table 11.5: GD -> IE Code Transition (LP64)
58 .byte 0x66
59 leaq tlsshared0@tlsgd(%rip),%rdi
60 .byte 0x66
61 rex64
62 call *__tls_get_addr@GOTPCREL(%rip)
63
64 .byte 0x66
65 leaq tlsshared1@tlsgd(%rip),%rdi
66 .byte 0x66
67 rex64
68 call *__tls_get_addr@GOTPCREL(%rip)
69
70 // Table 11.7: GD -> LE Code Transition (LP64)
71 .byte 0x66
72 leaq tls0@tlsgd(%rip),%rdi
73 .byte 0x66
74 rex64
75 call *__tls_get_addr@GOTPCREL(%rip)
76
77 .byte 0x66
78 leaq tls1@tlsgd(%rip),%rdi
79 .byte 0x66
80 rex64
81 call *__tls_get_addr@GOTPCREL(%rip)
82
83 // Table 11.9: LD -> LE Code Transition (LP64)
84 leaq tls0@tlsld(%rip),%rdi
85 call *__tls_get_addr@GOTPCREL(%rip)
86
87 leaq tls1@tlsld(%rip),%rdi
88 call *__tls_get_addr@GOTPCREL(%rip)
deps/lld/test/ELF/tls-static.s-1
...@@ -4,7 +4,6 @@...@@ -4,7 +4,6 @@
4// RUN: ld.lld -static %t -o %tout4// RUN: ld.lld -static %t -o %tout
5// RUN: ld.lld %t -o %tout5// RUN: ld.lld %t -o %tout
6// RUN: ld.lld -shared %tso -o %tshared6// RUN: ld.lld -shared %tso -o %tshared
7// RUN: ld.lld -static %t %tshared -o %tout
87
9.global _start8.global _start
10_start:9_start:
deps/lld/test/ELF/tls-weak-undef.s+1
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
44
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
6// RUN: %p/Inputs/tls-in-archive.s -o %t1.o6// RUN: %p/Inputs/tls-in-archive.s -o %t1.o
7// RUN: rm -f %t.a
7// RUN: llvm-ar cru %t.a %t1.o8// RUN: llvm-ar cru %t.a %t1.o
8// RUN: ld.lld %t.o %t.a -o %t9// RUN: ld.lld %t.o %t.a -o %t
910
deps/lld/test/ELF/trace-ar.s+1
...@@ -2,6 +2,7 @@...@@ -2,6 +2,7 @@
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar2.s -o %t.obj2.o4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar2.s -o %t.obj2.o
5# RUN: rm -f %t.boo.a
5# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o6# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o
67
7## Check how -t works with achieves8## Check how -t works with achieves
deps/lld/test/ELF/trace-symbols.s+2
...@@ -8,7 +8,9 @@...@@ -8,7 +8,9 @@
8# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t28# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2
9# RUN: ld.lld -shared %t1 -o %t1.so9# RUN: ld.lld -shared %t1 -o %t1.so
10# RUN: ld.lld -shared %t2 -o %t2.so10# RUN: ld.lld -shared %t2 -o %t2.so
11# RUN: rm -f %t1.a
11# RUN: llvm-ar rcs %t1.a %t112# RUN: llvm-ar rcs %t1.a %t1
13# RUN: rm -f %t2.a
12# RUN: llvm-ar rcs %t2.a %t214# RUN: llvm-ar rcs %t2.a %t2
1315
14# RUN: ld.lld -y foo -trace-symbol common -trace-symbol=hsymbol \16# RUN: ld.lld -y foo -trace-symbol common -trace-symbol=hsymbol \
deps/lld/test/ELF/undef-broken-debug.test+1-1
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
5# The debug info has a broken relocation. Check that we don't crash5# The debug info has a broken relocation. Check that we don't crash
6# and still report the undefined symbol.6# and still report the undefined symbol.
77
8# CHECK: error: unsupported relocation target while parsing debug info8# CHECK: error: {{.*}}.o: relocation R_X86_64_64 at 0x29 has unsupported target
9# CHECK: error: undefined symbol: bar9# CHECK: error: undefined symbol: bar
1010
11--- !ELF11--- !ELF
deps/lld/test/ELF/undef-version-script.s+3-3
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
66
7# CHECK: DynamicSymbols [7# CHECK: DynamicSymbols [
8# CHECK-NEXT: Symbol {8# CHECK-NEXT: Symbol {
9# CHECK-NEXT: Name: @9# CHECK-NEXT: Name:
10# CHECK-NEXT: Value: 0x010# CHECK-NEXT: Value: 0x0
11# CHECK-NEXT: Size: 011# CHECK-NEXT: Size: 0
12# CHECK-NEXT: Binding: Local (0x0)12# CHECK-NEXT: Binding: Local (0x0)
...@@ -15,7 +15,7 @@...@@ -15,7 +15,7 @@
15# CHECK-NEXT: Section: Undefined (0x0)15# CHECK-NEXT: Section: Undefined (0x0)
16# CHECK-NEXT: }16# CHECK-NEXT: }
17# CHECK-NEXT: Symbol {17# CHECK-NEXT: Symbol {
18# CHECK-NEXT: Name: bar@18# CHECK-NEXT: Name: bar
19# CHECK-NEXT: Value: 0x019# CHECK-NEXT: Value: 0x0
20# CHECK-NEXT: Size: 020# CHECK-NEXT: Size: 0
21# CHECK-NEXT: Binding: Weak (0x2)21# CHECK-NEXT: Binding: Weak (0x2)
...@@ -24,7 +24,7 @@...@@ -24,7 +24,7 @@
24# CHECK-NEXT: Section: Undefined (0x0)24# CHECK-NEXT: Section: Undefined (0x0)
25# CHECK-NEXT: }25# CHECK-NEXT: }
26# CHECK-NEXT: Symbol {26# CHECK-NEXT: Symbol {
27# CHECK-NEXT: Name: foo@27# CHECK-NEXT: Name: foo
28# CHECK-NEXT: Value: 0x028# CHECK-NEXT: Value: 0x0
29# CHECK-NEXT: Size: 029# CHECK-NEXT: Size: 0
30# CHECK-NEXT: Binding: Global (0x1)30# CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/undef-with-plt-addr-i686.s+2-2
...@@ -17,7 +17,7 @@ mov $set_data, %eax...@@ -17,7 +17,7 @@ mov $set_data, %eax
17// CHECK-NEXT: SHF_ALLOC17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: SHF_EXECINSTR18// CHECK-NEXT: SHF_EXECINSTR
19// CHECK-NEXT: ]19// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x1101020// CHECK-NEXT: Address: 0x401010
2121
22// CHECK: Name: set_data22// CHECK: Name: set_data
23// CHECK-NEXT: Value: 0x1102023// CHECK-NEXT: Value: 0x401020
deps/lld/test/ELF/undef.s+5
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-bad-debug.s -o %t4.o5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-bad-debug.s -o %t4.o
6# RUN: rm -f %t2.a
6# RUN: llvm-ar rc %t2.a %t2.o7# RUN: llvm-ar rc %t2.a %t2.o
7# RUN: not ld.lld %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s8# RUN: not ld.lld %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s
8# RUN: not ld.lld -pie %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s9# RUN: not ld.lld -pie %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s
...@@ -19,6 +20,9 @@...@@ -19,6 +20,9 @@
19# CHECK: >>> referenced by undef.s20# CHECK: >>> referenced by undef.s
20# CHECK: >>> {{.*}}:(.text+0x10)21# CHECK: >>> {{.*}}:(.text+0x10)
2122
23# CHECK: error: undefined symbol: vtable for Foo
24# CHECK: the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
25
22# CHECK: error: undefined symbol: zed226# CHECK: error: undefined symbol: zed2
23# CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a27# CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a
2428
...@@ -59,3 +63,4 @@ _start:...@@ -59,3 +63,4 @@ _start:
59 call bar63 call bar
60 call zed164 call zed1
61 call _Z3fooi65 call _Z3fooi
66 call _ZTV3Foo
deps/lld/test/ELF/verdef-defaultver.s+4-4
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
88
9# DSO: DynamicSymbols [9# DSO: DynamicSymbols [
10# DSO-NEXT: Symbol {10# DSO-NEXT: Symbol {
11# DSO-NEXT: Name: @11# DSO-NEXT: Name:
12# DSO-NEXT: Value: 0x012# DSO-NEXT: Value: 0x0
13# DSO-NEXT: Size: 013# DSO-NEXT: Size: 0
14# DSO-NEXT: Binding: Local14# DSO-NEXT: Binding: Local
...@@ -61,7 +61,7 @@...@@ -61,7 +61,7 @@
61# DSO-NEXT: Symbols [61# DSO-NEXT: Symbols [
62# DSO-NEXT: Symbol {62# DSO-NEXT: Symbol {
63# DSO-NEXT: Version: 063# DSO-NEXT: Version: 0
64# DSO-NEXT: Name: @64# DSO-NEXT: Name:
65# DSO-NEXT: }65# DSO-NEXT: }
66# DSO-NEXT: Symbol {66# DSO-NEXT: Symbol {
67# DSO-NEXT: Version: 267# DSO-NEXT: Version: 2
...@@ -112,7 +112,7 @@...@@ -112,7 +112,7 @@
112112
113# EXE: DynamicSymbols [113# EXE: DynamicSymbols [
114# EXE-NEXT: Symbol {114# EXE-NEXT: Symbol {
115# EXE-NEXT: Name: @115# EXE-NEXT: Name:
116# EXE-NEXT: Value: 0x0116# EXE-NEXT: Value: 0x0
117# EXE-NEXT: Size: 0117# EXE-NEXT: Size: 0
118# EXE-NEXT: Binding: Local118# EXE-NEXT: Binding: Local
...@@ -156,7 +156,7 @@...@@ -156,7 +156,7 @@
156# EXE-NEXT: Symbols [156# EXE-NEXT: Symbols [
157# EXE-NEXT: Symbol {157# EXE-NEXT: Symbol {
158# EXE-NEXT: Version: 0158# EXE-NEXT: Version: 0
159# EXE-NEXT: Name: @159# EXE-NEXT: Name:
160# EXE-NEXT: }160# EXE-NEXT: }
161# EXE-NEXT: Symbol {161# EXE-NEXT: Symbol {
162# EXE-NEXT: Version: 2162# EXE-NEXT: Version: 2
deps/lld/test/ELF/verdef.s+2-2
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14# DSO-NEXT: Symbols [14# DSO-NEXT: Symbols [
15# DSO-NEXT: Symbol {15# DSO-NEXT: Symbol {
16# DSO-NEXT: Version: 016# DSO-NEXT: Version: 0
17# DSO-NEXT: Name: @17# DSO-NEXT: Name:
18# DSO-NEXT: }18# DSO-NEXT: }
19# DSO-NEXT: Symbol {19# DSO-NEXT: Symbol {
20# DSO-NEXT: Version: 220# DSO-NEXT: Version: 2
...@@ -76,7 +76,7 @@...@@ -76,7 +76,7 @@
76# MAIN-NEXT: Symbols [76# MAIN-NEXT: Symbols [
77# MAIN-NEXT: Symbol {77# MAIN-NEXT: Symbol {
78# MAIN-NEXT: Version: 078# MAIN-NEXT: Version: 0
79# MAIN-NEXT: Name: @79# MAIN-NEXT: Name:
80# MAIN-NEXT: }80# MAIN-NEXT: }
81# MAIN-NEXT: Symbol {81# MAIN-NEXT: Symbol {
82# MAIN-NEXT: Version: 282# MAIN-NEXT: Version: 2
deps/lld/test/ELF/verneed.s+2-2
...@@ -76,7 +76,7 @@...@@ -76,7 +76,7 @@
7676
77# CHECK: DynamicSymbols [77# CHECK: DynamicSymbols [
78# CHECK-NEXT: Symbol {78# CHECK-NEXT: Symbol {
79# CHECK-NEXT: Name: @79# CHECK-NEXT: Name:
80# CHECK-NEXT: Value: 0x080# CHECK-NEXT: Value: 0x0
81# CHECK-NEXT: Size: 081# CHECK-NEXT: Size: 0
82# CHECK-NEXT: Binding: Local (0x0)82# CHECK-NEXT: Binding: Local (0x0)
...@@ -125,7 +125,7 @@...@@ -125,7 +125,7 @@
125# CHECK-NEXT: Symbols [125# CHECK-NEXT: Symbols [
126# CHECK-NEXT: Symbol {126# CHECK-NEXT: Symbol {
127# CHECK-NEXT: Version: 0127# CHECK-NEXT: Version: 0
128# CHECK-NEXT: Name: @128# CHECK-NEXT: Name:
129# CHECK-NEXT: }129# CHECK-NEXT: }
130# CHECK-NEXT: Symbol {130# CHECK-NEXT: Symbol {
131# CHECK-NEXT: Version: 2131# CHECK-NEXT: Version: 2
deps/lld/test/ELF/version-exclude-libs.s+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc %p/Inputs/versiondef.s -o %t.o -filetype=obj -triple=x86_64-pc-linux2// RUN: llvm-mc %p/Inputs/versiondef.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: rm -f %t.a
3// RUN: llvm-ar -r %t.a %t.o4// RUN: llvm-ar -r %t.a %t.o
4// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux5// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
5// RUN: ld.lld %t2.o %t.a --shared --exclude-libs ALL -o %t.so6// RUN: ld.lld %t2.o %t.a --shared --exclude-libs ALL -o %t.so
deps/lld/test/ELF/version-script-complex-wildcards.s+4-4
...@@ -4,14 +4,14 @@...@@ -4,14 +4,14 @@
4# RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script4# RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC6# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
7# ABC: Name: _Z3abbi@7# ABC: Name: _Z3abbi
8# ABC: Name: _Z3abci@@FOO8# ABC: Name: _Z3abci@@FOO
99
10# RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script10# RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script
11# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so11# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so
12# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB12# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB
13# ABB: Name: _Z3abbi@@FOO13# ABB: Name: _Z3abbi@@FOO
14# ABB: Name: _Z3abci@14# ABB: Name: _Z3abci
1515
16# RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script16# RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script
17# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so17# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
...@@ -34,8 +34,8 @@...@@ -34,8 +34,8 @@
34# RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script34# RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script
35# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so35# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so
36# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO36# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO
37# NO: Name: _Z3abbi@37# NO: Name: _Z3abbi
38# NO: Name: _Z3abci@38# NO: Name: _Z3abci
3939
40# RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script40# RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script
41# RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so41# RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so
deps/lld/test/ELF/version-script-extern-undefined.s+2-2
...@@ -8,11 +8,11 @@...@@ -8,11 +8,11 @@
8# CHECK: Symbols [8# CHECK: Symbols [
9# CHECK-NEXT: Symbol {9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Version: 010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @11# CHECK-NEXT: Name:
12# CHECK-NEXT: }12# CHECK-NEXT: }
13# CHECK-NEXT: Symbol {13# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Version: 114# CHECK-NEXT: Version: 1
15# CHECK-NEXT: Name: _Z3abbi@15# CHECK-NEXT: Name: _Z3abbi
16# CHECK-NEXT: }16# CHECK-NEXT: }
17# CHECK-NEXT: ]17# CHECK-NEXT: ]
1818
deps/lld/test/ELF/version-script-extern-wildcards.s+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
88
9# CHECK: Version symbols {9# CHECK: Version symbols {
10# CHECK: Symbols [10# CHECK: Symbols [
11# CHECK: Name: _Z3bari@11# CHECK: Name: _Z3bari
12# CHECK: Name: _Z3fooi@@FOO12# CHECK: Name: _Z3fooi@@FOO
13# CHECK: Name: _Z3zedi@@BAR13# CHECK: Name: _Z3zedi@@BAR
1414
deps/lld/test/ELF/version-script-extern.s+2-2
...@@ -12,7 +12,7 @@...@@ -12,7 +12,7 @@
1212
13# DSO: DynamicSymbols [13# DSO: DynamicSymbols [
14# DSO-NEXT: Symbol {14# DSO-NEXT: Symbol {
15# DSO-NEXT: Name: @15# DSO-NEXT: Name:
16# DSO-NEXT: Value: 0x016# DSO-NEXT: Value: 0x0
17# DSO-NEXT: Size: 017# DSO-NEXT: Size: 0
18# DSO-NEXT: Binding: Local18# DSO-NEXT: Binding: Local
...@@ -74,7 +74,7 @@...@@ -74,7 +74,7 @@
74# DSO-NEXT: Symbols [74# DSO-NEXT: Symbols [
75# DSO-NEXT: Symbol {75# DSO-NEXT: Symbol {
76# DSO-NEXT: Version: 076# DSO-NEXT: Version: 0
77# DSO-NEXT: Name: @77# DSO-NEXT: Name:
78# DSO-NEXT: }78# DSO-NEXT: }
79# DSO-NEXT: Symbol {79# DSO-NEXT: Symbol {
80# DSO-NEXT: Version: 380# DSO-NEXT: Version: 3
deps/lld/test/ELF/version-script-extern2.s+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8# CHECK: Symbols [8# CHECK: Symbols [
9# CHECK-NEXT: Symbol {9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Version: 010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @11# CHECK-NEXT: Name:
12# CHECK-NEXT: }12# CHECK-NEXT: }
13# CHECK-NEXT: Symbol {13# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Version: 214# CHECK-NEXT: Version: 2
deps/lld/test/ELF/version-script-hide-so-symbol.s+1-1
...@@ -12,7 +12,7 @@...@@ -12,7 +12,7 @@
1212
13# CHECK: DynamicSymbols [13# CHECK: DynamicSymbols [
14# CHECK-NEXT: Symbol {14# CHECK-NEXT: Symbol {
15# CHECK-NEXT: Name: @ (0)15# CHECK-NEXT: Name:
16# CHECK-NEXT: Value: 0x016# CHECK-NEXT: Value: 0x0
17# CHECK-NEXT: Size: 017# CHECK-NEXT: Size: 0
18# CHECK-NEXT: Binding: Local18# CHECK-NEXT: Binding: Local
deps/lld/test/ELF/version-script-locals-extern.s+4-4
...@@ -7,11 +7,11 @@...@@ -7,11 +7,11 @@
7# ABB: Symbols [7# ABB: Symbols [
8# ABB-NEXT: Symbol {8# ABB-NEXT: Symbol {
9# ABB-NEXT: Version: 09# ABB-NEXT: Version: 0
10# ABB-NEXT: Name: @10# ABB-NEXT: Name:
11# ABB-NEXT: }11# ABB-NEXT: }
12# ABB-NEXT: Symbol {12# ABB-NEXT: Symbol {
13# ABB-NEXT: Version: 113# ABB-NEXT: Version: 1
14# ABB-NEXT: Name: _Z3abci@14# ABB-NEXT: Name: _Z3abci
15# ABB-NEXT: }15# ABB-NEXT: }
16# ABB-NEXT: ]16# ABB-NEXT: ]
1717
...@@ -26,11 +26,11 @@...@@ -26,11 +26,11 @@
26# ABC: Symbols [26# ABC: Symbols [
27# ABC-NEXT: Symbol {27# ABC-NEXT: Symbol {
28# ABC-NEXT: Version: 028# ABC-NEXT: Version: 0
29# ABC-NEXT: Name: @29# ABC-NEXT: Name:
30# ABC-NEXT: }30# ABC-NEXT: }
31# ABC-NEXT: Symbol {31# ABC-NEXT: Symbol {
32# ABC-NEXT: Version: 132# ABC-NEXT: Version: 1
33# ABC-NEXT: Name: _Z3abbi@33# ABC-NEXT: Name: _Z3abbi
34# ABC-NEXT: }34# ABC-NEXT: }
35# ABC-NEXT: ]35# ABC-NEXT: ]
3636
deps/lld/test/ELF/version-script-symver2.s+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7# CHECK: Symbols [7# CHECK: Symbols [
8# CHECK-NEXT: Symbol {8# CHECK-NEXT: Symbol {
9# CHECK-NEXT: Version: 09# CHECK-NEXT: Version: 0
10# CHECK-NEXT: Name: @10# CHECK-NEXT: Name:
11# CHECK-NEXT: }11# CHECK-NEXT: }
12# CHECK-NEXT: Symbol {12# CHECK-NEXT: Symbol {
13# CHECK-NEXT: Version: 313# CHECK-NEXT: Version: 3
deps/lld/test/ELF/version-script-weak.s+1-1
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14# CHECK-NEXT: }14# CHECK-NEXT: }
15# CHECK-NEXT: ]15# CHECK-NEXT: ]
16# CHECK: Symbol {16# CHECK: Symbol {
17# CHECK: Name: foo@17# CHECK: Name: foo
18# CHECK-NEXT: Value: 0x018# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 019# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Weak20# CHECK-NEXT: Binding: Weak
deps/lld/test/ELF/version-script.s+14-14
...@@ -50,7 +50,7 @@...@@ -50,7 +50,7 @@
5050
51# DSO: DynamicSymbols [51# DSO: DynamicSymbols [
52# DSO-NEXT: Symbol {52# DSO-NEXT: Symbol {
53# DSO-NEXT: Name: @53# DSO-NEXT: Name:
54# DSO-NEXT: Value: 0x054# DSO-NEXT: Value: 0x0
55# DSO-NEXT: Size: 055# DSO-NEXT: Size: 0
56# DSO-NEXT: Binding: Local (0x0)56# DSO-NEXT: Binding: Local (0x0)
...@@ -59,7 +59,7 @@...@@ -59,7 +59,7 @@
59# DSO-NEXT: Section: Undefined (0x0)59# DSO-NEXT: Section: Undefined (0x0)
60# DSO-NEXT: }60# DSO-NEXT: }
61# DSO-NEXT: Symbol {61# DSO-NEXT: Symbol {
62# DSO-NEXT: Name: bar@62# DSO-NEXT: Name: bar
63# DSO-NEXT: Value: 0x063# DSO-NEXT: Value: 0x0
64# DSO-NEXT: Size: 064# DSO-NEXT: Size: 0
65# DSO-NEXT: Binding: Global (0x1)65# DSO-NEXT: Binding: Global (0x1)
...@@ -68,7 +68,7 @@...@@ -68,7 +68,7 @@
68# DSO-NEXT: Section: Undefined (0x0)68# DSO-NEXT: Section: Undefined (0x0)
69# DSO-NEXT: }69# DSO-NEXT: }
70# DSO-NEXT: Symbol {70# DSO-NEXT: Symbol {
71# DSO-NEXT: Name: foo1@71# DSO-NEXT: Name: foo1
72# DSO-NEXT: Value: 0x100072# DSO-NEXT: Value: 0x1000
73# DSO-NEXT: Size: 073# DSO-NEXT: Size: 0
74# DSO-NEXT: Binding: Global (0x1)74# DSO-NEXT: Binding: Global (0x1)
...@@ -77,7 +77,7 @@...@@ -77,7 +77,7 @@
77# DSO-NEXT: Section: .text77# DSO-NEXT: Section: .text
78# DSO-NEXT: }78# DSO-NEXT: }
79# DSO-NEXT: Symbol {79# DSO-NEXT: Symbol {
80# DSO-NEXT: Name: foo3@80# DSO-NEXT: Name: foo3
81# DSO-NEXT: Value: 0x100781# DSO-NEXT: Value: 0x1007
82# DSO-NEXT: Size: 082# DSO-NEXT: Size: 0
83# DSO-NEXT: Binding: Global (0x1)83# DSO-NEXT: Binding: Global (0x1)
...@@ -89,7 +89,7 @@...@@ -89,7 +89,7 @@
8989
90# DSO2: DynamicSymbols [90# DSO2: DynamicSymbols [
91# DSO2-NEXT: Symbol {91# DSO2-NEXT: Symbol {
92# DSO2-NEXT: Name: @92# DSO2-NEXT: Name:
93# DSO2-NEXT: Value: 0x093# DSO2-NEXT: Value: 0x0
94# DSO2-NEXT: Size: 094# DSO2-NEXT: Size: 0
95# DSO2-NEXT: Binding: Local (0x0)95# DSO2-NEXT: Binding: Local (0x0)
...@@ -98,7 +98,7 @@...@@ -98,7 +98,7 @@
98# DSO2-NEXT: Section: Undefined (0x0)98# DSO2-NEXT: Section: Undefined (0x0)
99# DSO2-NEXT: }99# DSO2-NEXT: }
100# DSO2-NEXT: Symbol {100# DSO2-NEXT: Symbol {
101# DSO2-NEXT: Name: bar@101# DSO2-NEXT: Name: bar
102# DSO2-NEXT: Value: 0x0102# DSO2-NEXT: Value: 0x0
103# DSO2-NEXT: Size: 0103# DSO2-NEXT: Size: 0
104# DSO2-NEXT: Binding: Global (0x1)104# DSO2-NEXT: Binding: Global (0x1)
...@@ -110,7 +110,7 @@...@@ -110,7 +110,7 @@
110110
111# VERDSO: DynamicSymbols [111# VERDSO: DynamicSymbols [
112# VERDSO-NEXT: Symbol {112# VERDSO-NEXT: Symbol {
113# VERDSO-NEXT: Name: @113# VERDSO-NEXT: Name:
114# VERDSO-NEXT: Value: 0x0114# VERDSO-NEXT: Value: 0x0
115# VERDSO-NEXT: Size: 0115# VERDSO-NEXT: Size: 0
116# VERDSO-NEXT: Binding: Local116# VERDSO-NEXT: Binding: Local
...@@ -119,7 +119,7 @@...@@ -119,7 +119,7 @@
119# VERDSO-NEXT: Section: Undefined119# VERDSO-NEXT: Section: Undefined
120# VERDSO-NEXT: }120# VERDSO-NEXT: }
121# VERDSO-NEXT: Symbol {121# VERDSO-NEXT: Symbol {
122# VERDSO-NEXT: Name: bar@122# VERDSO-NEXT: Name: bar
123# VERDSO-NEXT: Value: 0x0123# VERDSO-NEXT: Value: 0x0
124# VERDSO-NEXT: Size: 0124# VERDSO-NEXT: Size: 0
125# VERDSO-NEXT: Binding: Global125# VERDSO-NEXT: Binding: Global
...@@ -158,7 +158,7 @@...@@ -158,7 +158,7 @@
158158
159# ALL: DynamicSymbols [159# ALL: DynamicSymbols [
160# ALL-NEXT: Symbol {160# ALL-NEXT: Symbol {
161# ALL-NEXT: Name: @161# ALL-NEXT: Name:
162# ALL-NEXT: Value: 0x0162# ALL-NEXT: Value: 0x0
163# ALL-NEXT: Size: 0163# ALL-NEXT: Size: 0
164# ALL-NEXT: Binding: Local164# ALL-NEXT: Binding: Local
...@@ -167,7 +167,7 @@...@@ -167,7 +167,7 @@
167# ALL-NEXT: Section: Undefined167# ALL-NEXT: Section: Undefined
168# ALL-NEXT: }168# ALL-NEXT: }
169# ALL-NEXT: Symbol {169# ALL-NEXT: Symbol {
170# ALL-NEXT: Name: _start@170# ALL-NEXT: Name: _start
171# ALL-NEXT: Value:171# ALL-NEXT: Value:
172# ALL-NEXT: Size: 0172# ALL-NEXT: Size: 0
173# ALL-NEXT: Binding: Global173# ALL-NEXT: Binding: Global
...@@ -176,7 +176,7 @@...@@ -176,7 +176,7 @@
176# ALL-NEXT: Section: .text176# ALL-NEXT: Section: .text
177# ALL-NEXT: }177# ALL-NEXT: }
178# ALL-NEXT: Symbol {178# ALL-NEXT: Symbol {
179# ALL-NEXT: Name: bar@179# ALL-NEXT: Name: bar
180# ALL-NEXT: Value:180# ALL-NEXT: Value:
181# ALL-NEXT: Size: 0181# ALL-NEXT: Size: 0
182# ALL-NEXT: Binding: Global182# ALL-NEXT: Binding: Global
...@@ -185,7 +185,7 @@...@@ -185,7 +185,7 @@
185# ALL-NEXT: Section: Undefined185# ALL-NEXT: Section: Undefined
186# ALL-NEXT: }186# ALL-NEXT: }
187# ALL-NEXT: Symbol {187# ALL-NEXT: Symbol {
188# ALL-NEXT: Name: foo1@188# ALL-NEXT: Name: foo1
189# ALL-NEXT: Value:189# ALL-NEXT: Value:
190# ALL-NEXT: Size: 0190# ALL-NEXT: Size: 0
191# ALL-NEXT: Binding: Global191# ALL-NEXT: Binding: Global
...@@ -194,7 +194,7 @@...@@ -194,7 +194,7 @@
194# ALL-NEXT: Section: .text194# ALL-NEXT: Section: .text
195# ALL-NEXT: }195# ALL-NEXT: }
196# ALL-NEXT: Symbol {196# ALL-NEXT: Symbol {
197# ALL-NEXT: Name: foo2@197# ALL-NEXT: Name: foo2
198# ALL-NEXT: Value:198# ALL-NEXT: Value:
199# ALL-NEXT: Size: 0199# ALL-NEXT: Size: 0
200# ALL-NEXT: Binding: Global200# ALL-NEXT: Binding: Global
...@@ -203,7 +203,7 @@...@@ -203,7 +203,7 @@
203# ALL-NEXT: Section: .text203# ALL-NEXT: Section: .text
204# ALL-NEXT: }204# ALL-NEXT: }
205# ALL-NEXT: Symbol {205# ALL-NEXT: Symbol {
206# ALL-NEXT: Name: foo3@206# ALL-NEXT: Name: foo3
207# ALL-NEXT: Value:207# ALL-NEXT: Value:
208# ALL-NEXT: Size: 0208# ALL-NEXT: Size: 0
209# ALL-NEXT: Binding: Global209# ALL-NEXT: Binding: Global
deps/lld/test/ELF/version-wildcard.test+2-2
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
77
8# CHECK: DynamicSymbols [8# CHECK: DynamicSymbols [
9# CHECK-NEXT: Symbol {9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Name: @10# CHECK-NEXT: Name:
11# CHECK-NEXT: Value: 0x011# CHECK-NEXT: Value: 0x0
12# CHECK-NEXT: Size: 012# CHECK-NEXT: Size: 0
13# CHECK-NEXT: Binding: Local13# CHECK-NEXT: Binding: Local
...@@ -52,7 +52,7 @@...@@ -52,7 +52,7 @@
5252
53# MIX: DynamicSymbols [53# MIX: DynamicSymbols [
54# MIX-NEXT: Symbol {54# MIX-NEXT: Symbol {
55# MIX-NEXT: Name: @55# MIX-NEXT: Name:
56# MIX-NEXT: Value: 0x056# MIX-NEXT: Value: 0x0
57# MIX-NEXT: Size: 057# MIX-NEXT: Size: 0
58# MIX-NEXT: Binding: Local58# MIX-NEXT: Binding: Local
deps/lld/test/ELF/visibility.s+1-1
...@@ -82,7 +82,7 @@...@@ -82,7 +82,7 @@
8282
83// CHECK: DynamicSymbols [83// CHECK: DynamicSymbols [
84// CHECK-NEXT: Symbol {84// CHECK-NEXT: Symbol {
85// CHECK-NEXT: Name: @85// CHECK-NEXT: Name:
86// CHECK-NEXT: Value: 0x086// CHECK-NEXT: Value: 0x0
87// CHECK-NEXT: Size: 087// CHECK-NEXT: Size: 0
88// CHECK-NEXT: Binding: Local88// CHECK-NEXT: Binding: Local
deps/lld/test/ELF/weak-undef-export.s+2-2
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
88
9# CHECK: DynamicSymbols [9# CHECK: DynamicSymbols [
10# CHECK-NEXT: Symbol {10# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name: @ (0)11# CHECK-NEXT: Name:
12# CHECK-NEXT: Value: 0x012# CHECK-NEXT: Value: 0x0
13# CHECK-NEXT: Size: 013# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Local (0x0)14# CHECK-NEXT: Binding: Local (0x0)
...@@ -17,7 +17,7 @@...@@ -17,7 +17,7 @@
17# CHECK-NEXT: Section: Undefined (0x0)17# CHECK-NEXT: Section: Undefined (0x0)
18# CHECK-NEXT: }18# CHECK-NEXT: }
19# CHECK-NEXT: Symbol {19# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: foo@ (1)20# CHECK-NEXT: Name: foo
21# CHECK-NEXT: Value: 0x021# CHECK-NEXT: Value: 0x0
22# CHECK-NEXT: Size: 022# CHECK-NEXT: Size: 0
23# CHECK-NEXT: Binding: Weak (0x2)23# CHECK-NEXT: Binding: Weak (0x2)
deps/lld/test/ELF/weak-undef.s+2-2
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
55
6# CHECK: DynamicSymbols [6# CHECK: DynamicSymbols [
7# CHECK-NEXT: Symbol {7# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @8# CHECK-NEXT: Name:
9# CHECK-NEXT: Value: 0x09# CHECK-NEXT: Value: 0x0
10# CHECK-NEXT: Size: 010# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local (0x0)11# CHECK-NEXT: Binding: Local (0x0)
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14# CHECK-NEXT: Section: Undefined (0x0)14# CHECK-NEXT: Section: Undefined (0x0)
15# CHECK-NEXT: }15# CHECK-NEXT: }
16# CHECK-NEXT: Symbol {16# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: foo@17# CHECK-NEXT: Name: foo
18# CHECK-NEXT: Value: 0x018# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 019# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Weak20# CHECK-NEXT: Binding: Weak
deps/lld/test/ELF/wrap-entry.s created+13
...@@ -0,0 +1,13 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4// RUN: ld.lld -o %t.exe %t.o -wrap=_start
5// RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
6
7// CHECK: Entry: 0x201001
8
9.global _start, __wrap__start
10_start:
11 nop
12__wrap__start:
13 nop
deps/lld/test/ELF/wrap-no-real.s+6-52
...@@ -15,60 +15,14 @@...@@ -15,60 +15,14 @@
15// CHECK-NEXT: movl $0x11010, %edx15// CHECK-NEXT: movl $0x11010, %edx
16// CHECK-NEXT: movl $0x11000, %edx16// CHECK-NEXT: movl $0x11000, %edx
1717
18// RUN: llvm-readobj -t %t | FileCheck -check-prefix=SYM %s18// RUN: llvm-objdump -t %t | FileCheck -check-prefix=SYM %s
1919
20// Test the full symbol table. It is verbose, but lld at times
21// produced duplicated symbols which are hard to test otherwise.
2220
23// SYM: Symbols [21// SYM: 0000000000202000 .dynamic 00000000 .hidden _DYNAMIC
24// SYM-NEXT: Symbol {22// SYM-NEXT: 0000000000011000 *ABS* 00000000 __real_foo
25// SYM-NEXT: Name: (0)23// SYM-NEXT: 0000000000011010 *ABS* 00000000 __wrap_foo
26// SYM-NEXT: Value:24// SYM-NEXT: 0000000000201000 .text 00000000 _start
27// SYM-NEXT: Size:25// SYM-NEXT: 0000000000011000 *ABS* 00000000 foo
28// SYM-NEXT: Binding:
29// SYM-NEXT: Type
30// SYM-NEXT: Other:
31// SYM-NEXT: Section:
32// SYM-NEXT: }
33// SYM-NEXT: Symbol {
34// SYM-NEXT: Name: _DYNAMIC
35// SYM-NEXT: Value:
36// SYM-NEXT: Size:
37// SYM-NEXT: Binding:
38// SYM-NEXT: Type:
39// SYM-NEXT: Other [
40// SYM-NEXT: STV_HIDDEN
41// SYM-NEXT: ]
42// SYM-NEXT: Section: .dynamic
43// SYM-NEXT: }
44// SYM-NEXT: Symbol {
45// SYM-NEXT: Name: foo
46// SYM-NEXT: Value: 0x11000
47// SYM-NEXT: Size:
48// SYM-NEXT: Binding:
49// SYM-NEXT: Type:
50// SYM-NEXT: Other:
51// SYM-NEXT: Section:
52// SYM-NEXT: }
53// SYM-NEXT: Symbol {
54// SYM-NEXT: Name: _start
55// SYM-NEXT: Value:
56// SYM-NEXT: Size:
57// SYM-NEXT: Binding:
58// SYM-NEXT: Type
59// SYM-NEXT: Other:
60// SYM-NEXT: Section:
61// SYM-NEXT: }
62// SYM-NEXT: Symbol {
63// SYM-NEXT: Name: __wrap_foo
64// SYM-NEXT: Value: 0x11010
65// SYM-NEXT: Size:
66// SYM-NEXT: Binding:
67// SYM-NEXT: Type:
68// SYM-NEXT: Other:
69// SYM-NEXT: Section:
70// SYM-NEXT: }
71// SYM-NEXT: ]
7226
73.global _start27.global _start
74_start:28_start:
deps/lld/test/ELF/wrap-plt.s created+45
...@@ -0,0 +1,45 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3
4// RUN: ld.lld -o %t2 %t -wrap foo -shared
5// RUN: llvm-readobj -s -r %t2 | FileCheck %s
6// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
7
8// CHECK: Name: .plt
9// CHECK-NEXT: Type: SHT_PROGBITS
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: SHF_EXECINSTR
13// CHECK-NEXT: ]
14// CHECK-NEXT: Address: 0x1020
15// CHECK-NEXT: Offset:
16// CHECK-NEXT: Size: 48
17// CHECK-NEXT: Link: 0
18// CHECK-NEXT: Info: 0
19// CHECK-NEXT: AddressAlignment: 16
20
21// CHECK: Relocations [
22// CHECK-NEXT: Section ({{.*}}) .rela.plt {
23// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT __wrap_foo 0x0
24// CHECK-NEXT: 0x2020 R_X86_64_JUMP_SLOT _start 0x0
25// CHECK-NEXT: }
26// CHECK-NEXT: ]
27
28// DISASM: _start:
29// DISASM-NEXT: jmp 41
30// DISASM-NEXT: jmp 36
31// DISASM-NEXT: jmp 47
32
33.global foo
34foo:
35 nop
36
37.global __wrap_foo
38__wrap_foo:
39 nop
40
41.global _start
42_start:
43 jmp foo@plt
44 jmp __wrap_foo@plt
45 jmp _start@plt
deps/lld/test/ELF/wrap-with-archive.s created+13
...@@ -0,0 +1,13 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-with-archive.s -o %t2
4// RUN: llvm-ar rcs %t3 %t2
5// RUN: ld.lld -o %t4 %t %t3 -wrap get_executable_start
6
7// Regression test for https://bugs.llvm.org/show_bug.cgi?id=40134
8
9.global get_executable_start
10.global _start
11
12_start:
13 jmp get_executable_start
deps/lld/test/ELF/wrap.s+1-1
...@@ -34,7 +34,7 @@...@@ -34,7 +34,7 @@
34// SYM2-NEXT: STV_PROTECTED34// SYM2-NEXT: STV_PROTECTED
35// SYM2-NEXT: ]35// SYM2-NEXT: ]
36// SYM3: Name: __real_foo36// SYM3: Name: __real_foo
37// SYM3-NEXT: Value: 0x1102037// SYM3-NEXT: Value: 0x11000
38// SYM3-NEXT: Size:38// SYM3-NEXT: Size:
39// SYM3-NEXT: Binding: Global39// SYM3-NEXT: Binding: Global
40// SYM3-NEXT: Type: None40// SYM3-NEXT: Type: None
deps/lld/test/ELF/x86-64-combined-dynrel.s created+40
...@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc --triple=x86_64-pc-linux -filetype=obj -o %t.o %s
3# RUN: echo "SECTIONS { \
4# RUN: .text : { *(.text) } \
5# RUN: .rela.dyn : { *(.rela.dyn) *(.rela.plt) } \
6# RUN: } " > %t.script
7# RUN: ld.lld %t.o -o %t.so --shared --script %t.script
8# RUN: llvm-readobj --section-headers --dynamic-table %t.so | FileCheck %s
9
10// The linker script above combines the .rela.dyn and .rela.plt into a single
11// table. ELF is clear that the DT_PLTRELSZ should match the subset of
12// relocations that is associated with the PLT. It is less clear about what
13// the value of DT_RELASZ should be. ELF implies that it should be the size
14// of the single table so that DT_RELASZ includes DT_PLTRELSZ. The loader in
15// glibc permits this as long as .rela.plt comes after .rela.dyn in the
16// combined table.
17
18 .text
19 .globl func
20 .type func, %function
21 .globl foo
22 .type foo, %object
23
24 .globl _start
25 .type _start, %function
26_start:
27 call func@plt
28 movq func@GOTPCREL (%rip), %rax
29
30# CHECK: Name: .rela.dyn
31# CHECK-NEXT: Type: SHT_RELA
32# CHECK-NEXT: Flags [
33# CHECK-NEXT: SHF_ALLOC
34# CHECK-NEXT: ]
35# CHECK-NEXT: Address:
36# CHECK-NEXT: Offset:
37# CHECK-NEXT: Size: 48
38
39# CHECK: 0x0000000000000008 RELASZ 48
40# CHECK: 0x0000000000000002 PLTRELSZ 24
deps/lld/test/ELF/x86-64-reloc-error2.s+1-1
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
44
5## Check we are able to find a function symbol that encloses5## Check we are able to find a function symbol that encloses
6## a given location when reporting error messages.6## a given location when reporting error messages.
7# CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]7# CHECK: {{.*}}.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
88
9# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.9# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
10.section .rodata.str1,"aMS",@progbits,110.section .rodata.str1,"aMS",@progbits,1
deps/lld/test/ELF/x86-64-reloc-gotoff64.s+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -shared -o %t.so3// RUN: ld.lld %t.o -shared -o %t.so
4// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION4// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
5// RUN: llvm-objdump -d %t.so | FileCheck %s5// RUN: llvm-objdump -d %t.so | FileCheck %s
66
7// SECTION: .dynamic DYNAMIC 00000000000030007// SECTION: .dynamic DYNAMIC 0000000000003000
deps/lld/test/ELF/x86-64-reloc-gotpc64.s+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -shared -o %t.so3// RUN: ld.lld %t.o -shared -o %t.so
4// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION4// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
5// RUN: llvm-objdump -d %t.so | FileCheck %s5// RUN: llvm-objdump -d %t.so | FileCheck %s
66
7// SECTION: .got PROGBITS 0000000000003070 003070 0000007// SECTION: .got PROGBITS 0000000000003070 003070 000000
deps/lld/test/ELF/x86-64-reloc-range-debug-loc.s+1-1
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
55
6## Check we are able to report file and location from debug information6## Check we are able to report file and location from debug information
7## when reporting such kind of errors.7## when reporting such kind of errors.
8# CHECK: error: test.s:3: relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]8# CHECK: error: test.s:3:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
99
10.section .text,"ax",@progbits10.section .text,"ax",@progbits
11foo:11foo:
deps/lld/test/ELF/x86-64-reloc-range.s+2
...@@ -1,6 +1,8 @@...@@ -1,6 +1,8 @@
1// REQUIRES: x861// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj2// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
3// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s3// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
4// RUN: ld.lld --noinhibit-exec -shared %t.o -o %t 2>&1 | FileCheck %s
5// RUN: ls %t
46
5// CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647]7// CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647]
6// CHECK-NOT: relocation8// CHECK-NOT: relocation
deps/lld/test/ELF/x86-64-retpoline-znow-static-iplt.s created+26
...@@ -0,0 +1,26 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld -z retpolineplt -z now %t.o -o %t
4# RUN: llvm-objdump -d -no-show-raw-insn %t | FileCheck %s
5
6#0x201001+5 + 42 = 0x201030 (foo@plt)
7# CHECK: _start:
8# CHECK-NEXT: 201001: callq 42
9
10#Static IPLT header due to -z retpolineplt
11# CHECK: 0000000000201010 .plt:
12# CHECK-NEXT: 201010: callq 11 <.plt+0x10>
13# CHECK-NEXT: 201015: pause
14# CHECK-NEXT: 201017: lfence
15#foo@plt
16# CHECK: 201030: movq 4041(%rip), %r11
17# CHECK-NEXT: 201037: jmp -44 <.plt>
18
19.type foo STT_GNU_IFUNC
20.globl foo
21foo:
22 ret
23
24.globl _start
25_start:
26 call foo
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-fail.s+8-4
...@@ -1,14 +1,18 @@...@@ -1,14 +1,18 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t2.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-extra.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t3.o
45
5# RUN: not ld.lld --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s6# RUN: not ld.lld --defsym __morestack=0x100 --defsym __more_stack_nonsplit=0x200 %t1.o %t2.o %t3.o -o %t 2>&1 | FileCheck %s
67
7# An unknown prologue gives a match failure8# An unknown prologue gives a match failure
8# CHECK: unable to adjust the enclosing function's9# CHECK: error: {{.*}}.o:(.text): unknown_prologue (with -fsplit-stack) calls non_split (without -fsplit-stack), but couldn't adjust its prologue
910
10# RUN: not ld.lld -r --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s -check-prefix=RELOCATABLE11# RUN: not ld.lld -r --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s -check-prefix=RELOCATABLE
11# RELOCATABLE: Cannot mix split-stack and non-split-stack in a relocatable link12# RELOCATABLE: cannot mix split-stack and non-split-stack in a relocatable link
13
14# RUN: not ld.lld --defsym __morestack=0x100 --defsym _start=0x300 %t1.o %t2.o %t3.o -o %t 2>&1 | FileCheck %s -check-prefix=ERROR
15# ERROR: Mixing split-stack objects requires a definition of __morestack_non_split
1216
13 .text17 .text
1418
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-shared.s created+31
...@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-extra.s -o %t2.o
3# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t2.o -o %t4.so -shared
4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
6# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t4.so -o %t
7# RUN: llvm-objdump -d %t | FileCheck %s
8
9# For a cross .so call, make sure lld produced the conservative call to __morestack_non_split.
10# CHECK: prologue1_cross_so_call:
11# CHECK-NEXT: stc{{.*$}}
12# CHECK-NEXT: nopl{{.*$}}
13# CHECK: jae{{.*$}}
14# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
15
16 .text
17
18 .global prologue1_cross_so_call
19 .type prologue1_cross_so_call,@function
20prologue1_cross_so_call:
21 cmp %fs:0x70,%rsp
22 jae 1f
23 callq __morestack
24 retq
251:
26 callq split
27 retq
28 .size prologue1_cross_so_call,. - prologue1_cross_so_call
29
30 .section .note.GNU-stack,"",@progbits
31 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-silent.s+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t2.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t2.o
44
5# RUN: ld.lld --defsym __morestack=0x100 %t1.o %t2.o -o %t5# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o -o %t
6# RUN: llvm-objdump -d %t 2>&1 | FileCheck %s6# RUN: llvm-objdump -d %t 2>&1 | FileCheck %s
77
8# An unknown prologue ordinarily gives a match failure, except that this8# An unknown prologue ordinarily gives a match failure, except that this
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-success.s+13-22
...@@ -1,8 +1,9 @@...@@ -1,8 +1,9 @@
1# REQUIRES: x861# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t2.o3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-extra.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-main.s -o %t3.o
45
5# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o -o %t -z notext6# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o %t3.o -o %t -z notext
6# RUN: llvm-objdump -d %t | FileCheck %s7# RUN: llvm-objdump -d %t | FileCheck %s
78
8# Avoid duplicating the prologue for every test via macros.9# Avoid duplicating the prologue for every test via macros.
...@@ -25,11 +26,11 @@ prologue1_calls_\function_to_call:...@@ -25,11 +26,11 @@ prologue1_calls_\function_to_call:
25 .size prologue1_calls_\function_to_call,. - prologue1_calls_\function_to_call26 .size prologue1_calls_\function_to_call,. - prologue1_calls_\function_to_call
26.endm27.endm
2728
28.macro prologue2 function_to_call register29.macro prologue2 function_to_call register compare_amount
29 .global prologue2_calls_\function_to_call\register30 .global prologue2_calls_\function_to_call\register
30 .type prologue2_calls_\function_to_call\register,@function31 .type prologue2_calls_\function_to_call\register,@function
31prologue2_calls_\function_to_call\register:32prologue2_calls_\function_to_call\register:
32 lea -0x200(%rsp),%\register33 lea -\compare_amount(%rsp),%\register
33 cmp %fs:0x70,%\register34 cmp %fs:0x70,%\register
34 jae 1f35 jae 1f
35 callq __morestack36 callq __morestack
...@@ -65,20 +66,20 @@ prologue1 split...@@ -65,20 +66,20 @@ prologue1 split
65# calls plain __morestack, that any raw bytes written to the prologue66# calls plain __morestack, that any raw bytes written to the prologue
66# make sense, and that the register number is preserved.67# make sense, and that the register number is preserved.
67# CHECK: prologue2_calls_splitr10:68# CHECK: prologue2_calls_splitr10:
68# CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r1069# CHECK-NEXT: lea{{.*}} -512(%rsp),{{.*}}%r10
69# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}70# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}
70# CHECK: jae{{.*}}71# CHECK: jae{{.*}}
71# CHECK-NEXT: callq{{.*}}<__morestack>72# CHECK-NEXT: callq{{.*}}<__morestack>
7273
73prologue2 split r1074prologue2 split r10 0x200
7475
75# CHECK: prologue2_calls_splitr11:76# CHECK: prologue2_calls_splitr11:
76# CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r1177# CHECK-NEXT: lea{{.*}} -256(%rsp),{{.*}}%r11
77# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}78# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}
78# CHECK: jae{{.*}}79# CHECK: jae{{.*}}
79# CHECK-NEXT: callq{{.*}}<__morestack>80# CHECK-NEXT: callq{{.*}}<__morestack>
8081
81prologue2 split r1182prologue2 split r11 0x100
8283
83# For split-stack code calling non-split-stack code, ensure prologue v184# For split-stack code calling non-split-stack code, ensure prologue v1
84# calls __morestack_non_split, and that any raw bytes written to the prologue85# calls __morestack_non_split, and that any raw bytes written to the prologue
...@@ -95,30 +96,20 @@ prologue1 non_split...@@ -95,30 +96,20 @@ prologue1 non_split
95# calls __morestack_non_split, that any raw bytes written to the prologue96# calls __morestack_non_split, that any raw bytes written to the prologue
96# make sense, and that the register number is preserved97# make sense, and that the register number is preserved
97# CHECK: prologue2_calls_non_splitr10:98# CHECK: prologue2_calls_non_splitr10:
98# CHECK-NEXT: lea{{.*$}}99# CHECK-NEXT: lea{{.*}} -16640(%rsp),{{.*}}%r10
99# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r10100# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r10
100# CHECK: jae{{.*$}}101# CHECK: jae{{.*$}}
101# CHECK-NEXT: callq{{.*}}<__morestack_non_split>102# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
102103
103prologue2 non_split r10104prologue2 non_split r10 0x100
104105
105# CHECK: prologue2_calls_non_splitr11:106# CHECK: prologue2_calls_non_splitr11:
106# CHECK-NEXT: lea{{.*$}}107# CHECK-NEXT: lea{{.*}} -16896(%rsp),{{.*}}%r11
107# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r11108# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r11
108# CHECK: jae{{.*$}}109# CHECK: jae{{.*$}}
109# CHECK-NEXT: callq{{.*}}<__morestack_non_split>110# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
110111
111prologue2 non_split r11112prologue2 non_split r11 0x200
112# call foo@plt # for code-coverage.
113
114
115
116 .global split
117 .type split,@function
118split:
119 retq
120
121 .size split,. - split
122113
123 .section .note.GNU-stack,"",@progbits114 .section .note.GNU-stack,"",@progbits
124 .section .note.GNU-split-stack,"",@progbits115 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/znotext-plt-relocations-protected.s+6-1
...@@ -4,7 +4,12 @@...@@ -4,7 +4,12 @@
4# RUN: ld.lld %t2.o -o %t2.so -shared4# RUN: ld.lld %t2.o -o %t2.so -shared
5# RUN: not ld.lld -z notext %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s5# RUN: not ld.lld -z notext %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s
66
7# CHECK: error: cannot preempt symbol: foo7# CHECK: error: cannot preempt symbol: foo
8# CHECK-NEXT: >>> defined in {{.*}}2.so
9# CHECK-NEXT: >>> referenced by test.cpp
10# CHECK-NEXT: >>> {{.*}}.o:(.text+0x0)
11
12.file "test.cpp"
813
9.global _start14.global _start
10_start:15_start:
deps/lld/test/ELF/zstack-size.s+3
...@@ -6,6 +6,9 @@...@@ -6,6 +6,9 @@
6# RUN: ld.lld -z stack-size=0 %t -o %t26# RUN: ld.lld -z stack-size=0 %t -o %t2
7# RUN: llvm-readobj -program-headers %t2 | FileCheck %s -check-prefix=CHECK27# RUN: llvm-readobj -program-headers %t2 | FileCheck %s -check-prefix=CHECK2
88
9# RUN: ld.lld -z stack-size=0x2000 -z stack-size=0x1000 %t -o %t3
10# RUN: llvm-readobj -program-headers %t3 | FileCheck %s -check-prefix=CHECK1
11
9.global _start12.global _start
10_start:13_start:
11 nop14 nop
deps/lld/test/MinGW/driver.test+6
...@@ -145,3 +145,9 @@ RUN: ld.lld -### foo.o -m i386pep --Map bar.map | FileCheck -check-prefix=MAP %s...@@ -145,3 +145,9 @@ RUN: ld.lld -### foo.o -m i386pep --Map bar.map | FileCheck -check-prefix=MAP %s
145RUN: ld.lld -### foo.o -m i386pep -Map=bar.map | FileCheck -check-prefix=MAP %s145RUN: ld.lld -### foo.o -m i386pep -Map=bar.map | FileCheck -check-prefix=MAP %s
146RUN: ld.lld -### foo.o -m i386pep --Map=bar.map | FileCheck -check-prefix=MAP %s146RUN: ld.lld -### foo.o -m i386pep --Map=bar.map | FileCheck -check-prefix=MAP %s
147MAP: -lldmap:bar.map147MAP: -lldmap:bar.map
148
149RUN: ld.lld -### foo.o -m i386pe -require-defined _foo --require-defined _bar -require-defined=_baz --require-defined=_foo2 | FileCheck -check-prefix=REQUIRE-DEFINED %s
150REQUIRE-DEFINED: -include:_foo -include:_bar -include:_baz -include:_foo2
151
152RUN: ld.lld -### -m i386pep foo.o -Llibpath | FileCheck -check-prefix LIBPATH %s
153LIBPATH: -libpath:libpath
deps/lld/test/lit.cfg.py+14-4
...@@ -45,13 +45,18 @@ tool_patterns = [...@@ -45,13 +45,18 @@ tool_patterns = [
4545
46llvm_config.add_tool_substitutions(tool_patterns)46llvm_config.add_tool_substitutions(tool_patterns)
4747
48# LLD tests tend to be flaky on NetBSD, so add some retries.
49# We don't do this on other platforms because it's slower.
50if platform.system() in ['NetBSD']:
51 config.test_retry_attempts = 2
52
48# When running under valgrind, we mangle '-vg' onto the end of the triple so we53# When running under valgrind, we mangle '-vg' onto the end of the triple so we
49# can check it with XFAIL and XTARGET.54# can check it with XFAIL and XTARGET.
50if lit_config.useValgrind:55if lit_config.useValgrind:
51 config.target_triple += '-vg'56 config.target_triple += '-vg'
5257
53# Running on ELF based *nix58# Running on ELF based *nix
54if platform.system() in ['FreeBSD', 'Linux']:59if platform.system() in ['FreeBSD', 'NetBSD', 'Linux']:
55 config.available_features.add('system-linker-elf')60 config.available_features.add('system-linker-elf')
5661
57# Set if host-cxxabi's demangler can handle target's symbols.62# Set if host-cxxabi's demangler can handle target's symbols.
...@@ -67,7 +72,9 @@ llvm_config.feature_config(...@@ -67,7 +72,9 @@ llvm_config.feature_config(
67 'AVR': 'avr',72 'AVR': 'avr',
68 'Hexagon': 'hexagon',73 'Hexagon': 'hexagon',
69 'Mips': 'mips',74 'Mips': 'mips',
75 'MSP430': 'msp430',
70 'PowerPC': 'ppc',76 'PowerPC': 'ppc',
77 'RISCV': 'riscv',
71 'Sparc': 'sparc',78 'Sparc': 'sparc',
72 'WebAssembly': 'wasm',79 'WebAssembly': 'wasm',
73 'X86': 'x86'})80 'X86': 'x86'})
...@@ -93,7 +100,10 @@ if config.have_dia_sdk:...@@ -93,7 +100,10 @@ if config.have_dia_sdk:
93tar_executable = lit.util.which('tar', config.environment['PATH'])100tar_executable = lit.util.which('tar', config.environment['PATH'])
94if tar_executable:101if tar_executable:
95 tar_version = subprocess.Popen(102 tar_version = subprocess.Popen(
96 [tar_executable, '--version'], stdout=subprocess.PIPE, env={'LANG': 'C'})103 [tar_executable, '--version'],
97 if 'GNU tar' in tar_version.stdout.read().decode():104 stdout=subprocess.PIPE,
105 stderr=subprocess.PIPE,
106 env={'LANG': 'C'})
107 sout, _ = tar_version.communicate()
108 if 'GNU tar' in sout.decode():
98 config.available_features.add('gnutar')109 config.available_features.add('gnutar')
99 tar_version.wait()
deps/lld/test/lit.site.cfg.py.in+2-1
...@@ -25,7 +25,8 @@ except KeyError as e:...@@ -25,7 +25,8 @@ except KeyError as e:
25 key, = e.args25 key, = e.args
26 lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))26 lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
2727
28@LIT_SITE_CFG_IN_FOOTER@28import lit.llvm
29lit.llvm.initialize(lit_config, config)
2930
30# Let the main config do the real work.31# Let the main config do the real work.
31lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg.py")32lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg.py")
deps/lld/test/mach-o/cstring-sections.yaml+4-4
...@@ -36,25 +36,25 @@ sections:...@@ -36,25 +36,25 @@ sections:
36# CHECK: content: [ 61, 62, 63, 00 ]36# CHECK: content: [ 61, 62, 63, 00 ]
37# CHECK: merge: by-content37# CHECK: merge: by-content
38# CHECK: section-choice: custom-required38# CHECK: section-choice: custom-required
39# CHECK: section-name: __TEXT/__objc_methname39# CHECK: section-name: '__TEXT/__objc_methname'
40# CHECK: - scope: hidden40# CHECK: - scope: hidden
41# CHECK: type: c-string41# CHECK: type: c-string
42# CHECK: content: [ 64, 65, 66, 00 ]42# CHECK: content: [ 64, 65, 66, 00 ]
43# CHECK: merge: by-content43# CHECK: merge: by-content
44# CHECK: section-choice: custom-required44# CHECK: section-choice: custom-required
45# CHECK: section-name: __TEXT/__objc_methname45# CHECK: section-name: '__TEXT/__objc_methname'
46# CHECK: - scope: hidden46# CHECK: - scope: hidden
47# CHECK: type: c-string47# CHECK: type: c-string
48# CHECK: content: [ 61, 62, 63, 00 ]48# CHECK: content: [ 61, 62, 63, 00 ]
49# CHECK: merge: by-content49# CHECK: merge: by-content
50# CHECK: section-choice: custom-required50# CHECK: section-choice: custom-required
51# CHECK: section-name: __TEXT/__objc_classname51# CHECK: section-name: '__TEXT/__objc_classname'
52# CHECK: - scope: hidden52# CHECK: - scope: hidden
53# CHECK: type: c-string53# CHECK: type: c-string
54# CHECK: content: [ 67, 68, 69, 00 ]54# CHECK: content: [ 67, 68, 69, 00 ]
55# CHECK: merge: by-content55# CHECK: merge: by-content
56# CHECK: section-choice: custom-required56# CHECK: section-choice: custom-required
57# CHECK: section-name: __TEXT/__objc_classname57# CHECK: section-name: '__TEXT/__objc_classname'
58# CHECK: - scope: hidden58# CHECK: - scope: hidden
59# CHECK: type: c-string59# CHECK: type: c-string
60# CHECK: content: [ 61, 62, 63, 00 ]60# CHECK: content: [ 61, 62, 63, 00 ]
deps/lld/test/mach-o/parse-data-relocs-x86_64.yaml+1-1
...@@ -367,6 +367,6 @@ page-size: 0x00000000...@@ -367,6 +367,6 @@ page-size: 0x00000000
367# CHECK: type: unknown367# CHECK: type: unknown
368# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]368# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
369# CHECK: section-choice: custom-required369# CHECK: section-choice: custom-required
370# CHECK: section-name: __DATA/__custom370# CHECK: section-name: '__DATA/__custom'
371# CHECK: dead-strip: never371# CHECK: dead-strip: never
372372
deps/lld/test/mach-o/parse-data.yaml+1-1
...@@ -115,5 +115,5 @@ global-symbols:...@@ -115,5 +115,5 @@ global-symbols:
115# CHECK: type: unknown115# CHECK: type: unknown
116# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]116# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
117# CHECK: section-choice: custom-required117# CHECK: section-choice: custom-required
118# CHECK: section-name: __CUST/__custom118# CHECK: section-name: '__CUST/__custom'
119119
deps/lld/test/mach-o/sectcreate.yaml+1-1
...@@ -8,5 +8,5 @@...@@ -8,5 +8,5 @@
8# CHECK: type: sectcreate8# CHECK: type: sectcreate
9# CHECK: content: [ 68, 65, 6C, 6C, 6F, 0A ]9# CHECK: content: [ 68, 65, 6C, 6C, 6F, 0A ]
10# CHECK: section-choice: custom-required10# CHECK: section-choice: custom-required
11# CHECK: section-name: __DATA/__data11# CHECK: section-name: '__DATA/__data'
12# CHECK: dead-strip: never12# CHECK: dead-strip: never
deps/lld/test/wasm/Inputs/event-section1.ll created+9
...@@ -0,0 +1,9 @@
1target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2target triple = "wasm32-unknown-unknown"
3
4declare void @llvm.wasm.throw(i32, i8*)
5
6define void @foo(i8* %p) {
7 call void @llvm.wasm.throw(i32 0, i8* %p)
8 ret void
9}
deps/lld/test/wasm/Inputs/event-section2.ll created+9
...@@ -0,0 +1,9 @@
1target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2target triple = "wasm32-unknown-unknown"
3
4declare void @llvm.wasm.throw(i32, i8*)
5
6define void @bar(i8* %p) {
7 call void @llvm.wasm.throw(i32 0, i8* %p)
8 ret void
9}
deps/lld/test/wasm/Inputs/globals.yaml+1-1
...@@ -34,7 +34,7 @@ Sections:...@@ -34,7 +34,7 @@ Sections:
34 Offset: 0x0000000434 Offset: 0x00000004
35 - Type: CUSTOM35 - Type: CUSTOM
36 Name: linking36 Name: linking
37 Version: 137 Version: 2
38 SymbolTable:38 SymbolTable:
39 - Index: 039 - Index: 0
40 Kind: GLOBAL40 Kind: GLOBAL
deps/lld/test/wasm/Inputs/undefined-globals.yaml+1-1
...@@ -32,7 +32,7 @@ Sections:...@@ -32,7 +32,7 @@ Sections:
32 Offset: 0x0000000432 Offset: 0x00000004
33 - Type: CUSTOM33 - Type: CUSTOM
34 Name: linking34 Name: linking
35 Version: 135 Version: 2
36 SymbolTable:36 SymbolTable:
37 - Index: 037 - Index: 0
38 Kind: GLOBAL38 Kind: GLOBAL
deps/lld/test/wasm/alias.ll+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1; RUN: llc -filetype=obj -o %t.o %s1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: wasm-ld %t.o -o %t.wasm2; RUN: wasm-ld --export=start_alias %t.o -o %t.wasm
3; RUN: obj2yaml %t.wasm | FileCheck %s3; RUN: obj2yaml %t.wasm | FileCheck %s
44
5target triple = "wasm32-unknown-unknown"5target triple = "wasm32-unknown-unknown"
...@@ -25,7 +25,7 @@ entry:...@@ -25,7 +25,7 @@ entry:
25; CHECK-NEXT: FunctionTypes: [ 0, 0 ]25; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
26; CHECK-NEXT: - Type: TABLE26; CHECK-NEXT: - Type: TABLE
27; CHECK-NEXT: Tables:27; CHECK-NEXT: Tables:
28; CHECK-NEXT: - ElemType: ANYFUNC28; CHECK-NEXT: - ElemType: FUNCREF
29; CHECK-NEXT: Limits:29; CHECK-NEXT: Limits:
30; CHECK-NEXT: Flags: [ HAS_MAX ]30; CHECK-NEXT: Flags: [ HAS_MAX ]
31; CHECK-NEXT: Initial: 0x0000000131; CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/archive-export.ll created+50
...@@ -0,0 +1,50 @@
1Test that --export will also fetch lazy symbols from archives
2
3RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.o
4RUN: llc -filetype=obj %S/Inputs/archive1.ll -o %t.a1.o
5RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o
6RUN: rm -f %t.a
7RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o
8RUN: wasm-ld --export-dynamic --export=archive2_symbol -o %t.wasm %t.a %t.o
9RUN: obj2yaml %t.wasm | FileCheck %s
10RUN: wasm-ld --export-dynamic -o %t.wasm %t.a %t.o
11RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=NOEXPORT
12
13CHECK: Exports:
14CHECK-NEXT: - Name: memory
15CHECK-NEXT: Kind: MEMORY
16CHECK-NEXT: Index: 0
17CHECK-NEXT: - Name: __heap_base
18CHECK-NEXT: Kind: GLOBAL
19CHECK-NEXT: Index: 1
20CHECK-NEXT: - Name: __data_end
21CHECK-NEXT: Kind: GLOBAL
22CHECK-NEXT: Index: 2
23CHECK-NEXT: - Name: foo
24CHECK-NEXT: Kind: FUNCTION
25CHECK-NEXT: Index: 2
26CHECK-NEXT: - Name: bar
27CHECK-NEXT: Kind: FUNCTION
28CHECK-NEXT: Index: 3
29CHECK-NEXT: - Name: archive2_symbol
30CHECK-NEXT: Kind: FUNCTION
31CHECK-NEXT: Index: 4
32CHECK-NEXT: - Name: _start
33CHECK-NEXT: Kind: FUNCTION
34CHECK-NEXT: Index: 1
35CHECK-NEXT: - Type: CODE
36
37NOEXPORT: Exports:
38NOEXPORT-NEXT: - Name: memory
39NOEXPORT-NEXT: Kind: MEMORY
40NOEXPORT-NEXT: Index: 0
41NOEXPORT-NEXT: - Name: __heap_base
42NOEXPORT-NEXT: Kind: GLOBAL
43NOEXPORT-NEXT: Index: 1
44NOEXPORT-NEXT: - Name: __data_end
45NOEXPORT-NEXT: Kind: GLOBAL
46NOEXPORT-NEXT: Index: 2
47NOEXPORT-NEXT: - Name: _start
48NOEXPORT-NEXT: Kind: FUNCTION
49NOEXPORT-NEXT: Index: 1
50NOEXPORT-NEXT: - Type: CODE
deps/lld/test/wasm/archive.ll+1
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3; RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o3; RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o
4; RUN: llc -filetype=obj %S/Inputs/archive3.ll -o %t.a3.o4; RUN: llc -filetype=obj %S/Inputs/archive3.ll -o %t.a3.o
5; RUN: llc -filetype=obj %S/Inputs/hello.ll -o %t.hello.o5; RUN: llc -filetype=obj %S/Inputs/hello.ll -o %t.hello.o
6; RUN: rm -f %t.a
6; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o %t.hello.o7; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o %t.hello.o
7; RUN: rm -f %t.imports8; RUN: rm -f %t.imports
8; RUN: not wasm-ld %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s9; RUN: not wasm-ld %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s
deps/lld/test/wasm/call-indirect.ll+5-5
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o1; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
2; RUN: llc -filetype=obj %s -o %t.o2; RUN: llc -filetype=obj %s -o %t.o
3; RUN: wasm-ld -o %t.wasm %t2.o %t.o3; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55
6; bitcode generated from the following C code:6; bitcode generated from the following C code:
...@@ -60,7 +60,7 @@ define void @call_ptr(i64 (i64)* %arg) {...@@ -60,7 +60,7 @@ define void @call_ptr(i64 (i64)* %arg) {
60; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ]60; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ]
61; CHECK-NEXT: - Type: TABLE61; CHECK-NEXT: - Type: TABLE
62; CHECK-NEXT: Tables:62; CHECK-NEXT: Tables:
63; CHECK-NEXT: - ElemType: ANYFUNC63; CHECK-NEXT: - ElemType: FUNCREF
64; CHECK-NEXT: Limits:64; CHECK-NEXT: Limits:
65; CHECK-NEXT: Flags: [ HAS_MAX ]65; CHECK-NEXT: Flags: [ HAS_MAX ]
66; CHECK-NEXT: Initial: 0x0000000366; CHECK-NEXT: Initial: 0x00000003
...@@ -105,9 +105,6 @@ define void @call_ptr(i64 (i64)* %arg) {...@@ -105,9 +105,6 @@ define void @call_ptr(i64 (i64)* %arg) {
105; CHECK-NEXT: - Name: __data_end105; CHECK-NEXT: - Name: __data_end
106; CHECK-NEXT: Kind: GLOBAL106; CHECK-NEXT: Kind: GLOBAL
107; CHECK-NEXT: Index: 2107; CHECK-NEXT: Index: 2
108; CHECK-NEXT: - Name: _start
109; CHECK-NEXT: Kind: FUNCTION
110; CHECK-NEXT: Index: 4
111; CHECK-NEXT: - Name: bar108; CHECK-NEXT: - Name: bar
112; CHECK-NEXT: Kind: FUNCTION109; CHECK-NEXT: Kind: FUNCTION
113; CHECK-NEXT: Index: 1110; CHECK-NEXT: Index: 1
...@@ -117,6 +114,9 @@ define void @call_ptr(i64 (i64)* %arg) {...@@ -117,6 +114,9 @@ define void @call_ptr(i64 (i64)* %arg) {
117; CHECK-NEXT: - Name: foo114; CHECK-NEXT: - Name: foo
118; CHECK-NEXT: Kind: FUNCTION115; CHECK-NEXT: Kind: FUNCTION
119; CHECK-NEXT: Index: 3116; CHECK-NEXT: Index: 3
117; CHECK-NEXT: - Name: _start
118; CHECK-NEXT: Kind: FUNCTION
119; CHECK-NEXT: Index: 4
120; CHECK-NEXT: - Name: indirect_func120; CHECK-NEXT: - Name: indirect_func
121; CHECK-NEXT: Kind: GLOBAL121; CHECK-NEXT: Kind: GLOBAL
122; CHECK-NEXT: Index: 3122; CHECK-NEXT: Index: 3
deps/lld/test/wasm/comdats.ll+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o1; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o
2; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o2; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o
3; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o3; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o
4; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o4; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
5; RUN: obj2yaml %t.wasm | FileCheck %s5; RUN: obj2yaml %t.wasm | FileCheck %s
66
7target triple = "wasm32-unknown-unknown"7target triple = "wasm32-unknown-unknown"
deps/lld/test/wasm/compress-relocs.ll+7-3
...@@ -1,9 +1,11 @@...@@ -1,9 +1,11 @@
1; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o1; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
2; RUN: llc -filetype=obj %s -o %t.o2; RUN: llc -filetype=obj %s -o %t.o
3; RUN: wasm-ld -o %t.wasm %t2.o %t.o3; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
6; RUN: wasm-ld -O2 -o %t-compressed.wasm %t2.o %t.o6; RUN: obj2yaml %t-opt.wasm | FileCheck %s
7; RUN: not wasm-ld --compress-relocations -o %t-compressed.wasm %t2.o %t.o 2>&1 | FileCheck %s -check-prefix=ERROR
8; RUN: wasm-ld --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t2.o %t.o
7; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS9; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
810
9target triple = "wasm32-unknown-unknown-wasm"11target triple = "wasm32-unknown-unknown-wasm"
...@@ -18,5 +20,7 @@ entry:...@@ -18,5 +20,7 @@ entry:
18 ret void20 ret void
19}21}
2022
23; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
24
21; CHECK: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B25; CHECK: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
22; COMPRESS: Body: 41002802840821004100280280081100001A20001101001A0B26; COMPRESS: Body: 41002802840821004100280280081100001A20001101001A0B
deps/lld/test/wasm/cxx-mangling.ll+11-9
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1; RUN: llc -filetype=obj %s -o %t.o1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld --demangle -o %t_demangle.wasm %t.o2; RUN: wasm-ld --export=_Z3fooi --demangle -o %t_demangle.wasm %t.o
3; RUN: obj2yaml %t_demangle.wasm | FileCheck %s3; RUN: obj2yaml %t_demangle.wasm | FileCheck --check-prefixes=CHECK,DEMANGLE %s
4; RUN: wasm-ld --no-demangle -o %t_nodemangle.wasm %t.o4; RUN: wasm-ld --export=_Z3fooi --no-demangle -o %t_nodemangle.wasm %t.o
5; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s5; RUN: obj2yaml %t_nodemangle.wasm | FileCheck --check-prefixes=CHECK,MANGLE %s
66
7target triple = "wasm32-unknown-unknown"7target triple = "wasm32-unknown-unknown"
88
...@@ -32,12 +32,12 @@ define void @_start() {...@@ -32,12 +32,12 @@ define void @_start() {
32; CHECK-NEXT: - Name: __data_end32; CHECK-NEXT: - Name: __data_end
33; CHECK-NEXT: Kind: GLOBAL33; CHECK-NEXT: Kind: GLOBAL
34; CHECK-NEXT: Index: 234; CHECK-NEXT: Index: 2
35; CHECK-NEXT: - Name: _start
36; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 3
38; CHECK-NEXT: - Name: _Z3fooi35; CHECK-NEXT: - Name: _Z3fooi
39; CHECK-NEXT: Kind: FUNCTION36; CHECK-NEXT: Kind: FUNCTION
40; CHECK-NEXT: Index: 237; CHECK-NEXT: Index: 2
38; CHECK-NEXT: - Name: _start
39; CHECK-NEXT: Kind: FUNCTION
40; CHECK-NEXT: Index: 3
41; CHECK-NEXT: - Type: CODE41; CHECK-NEXT: - Type: CODE
42; CHECK-NEXT: Functions:42; CHECK-NEXT: Functions:
43; CHECK-NEXT: - Index: 043; CHECK-NEXT: - Index: 0
...@@ -58,9 +58,11 @@ define void @_start() {...@@ -58,9 +58,11 @@ define void @_start() {
58; CHECK-NEXT: - Index: 058; CHECK-NEXT: - Index: 0
59; CHECK-NEXT: Name: __wasm_call_ctors59; CHECK-NEXT: Name: __wasm_call_ctors
60; CHECK-NEXT: - Index: 160; CHECK-NEXT: - Index: 1
61; CHECK-NEXT: Name: 'undefined function bar(int)'61; DEMANGLE-NEXT: Name: 'undefined function bar(int)'
62; MANGLE-NEXT: Name: undefined function _Z3bari
62; CHECK-NEXT: - Index: 263; CHECK-NEXT: - Index: 2
63; CHECK-NEXT: Name: 'foo(int)'64; DEMANGLE-NEXT: Name: 'foo(int)'
65; MANGLE-NEXT: Name: _Z3fooi
64; CHECK-NEXT: - Index: 366; CHECK-NEXT: - Index: 3
65; CHECK-NEXT: Name: _start67; CHECK-NEXT: Name: _start
66; CHECK-NEXT: ...68; CHECK-NEXT: ...
deps/lld/test/wasm/data-layout.ll+10
...@@ -68,6 +68,16 @@ target triple = "wasm32-unknown-unknown"...@@ -68,6 +68,16 @@ target triple = "wasm32-unknown-unknown"
68; CHECK-MAX-NEXT: Initial: 0x0000000268; CHECK-MAX-NEXT: Initial: 0x00000002
69; CHECK-MAX-NEXT: Maximum: 0x0000000269; CHECK-MAX-NEXT: Maximum: 0x00000002
7070
71; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry --shared-memory \
72; RUN: --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \
73; RUN: %t.hello.o
74; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-SHARED
75
76; CHECK-SHARED: - Type: MEMORY
77; CHECK-SHARED-NEXT: Memories:
78; CHECK-SHARED-NEXT: - Flags: [ HAS_MAX, IS_SHARED ]
79; CHECK-SHARED-NEXT: Initial: 0x00000002
80; CHECK-SHARED-NEXT: Maximum: 0x00000002
7181
72; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o82; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o
73; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC83; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC
deps/lld/test/wasm/data-segment-merging.ll+17-34
...@@ -5,44 +5,27 @@ target triple = "wasm32-unknown-unknown"...@@ -5,44 +5,27 @@ target triple = "wasm32-unknown-unknown"
5@c = hidden global [9 x i8] c"whatever\00", align 15@c = hidden global [9 x i8] c"whatever\00", align 1
6@d = hidden global i32 42, align 46@d = hidden global i32 42, align 4
77
8@e = private constant [9 x i8] c"constant\00", align 1
9@f = private constant i8 43, align 4
10
8; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o11; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o
912
10; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o13; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o
11; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE14; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE
12; MERGE: - Type: DATA15; MERGE: - Type: DATA
13; MERGE-NEXT: Segments:16; MERGE: Segments:
14; MERGE-NEXT: - SectionOffset: 717; MERGE: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
15; MERGE-NEXT: MemoryIndex: 018; MERGE: Content: 636F6E7374616E74000000002B
16; MERGE-NEXT: Offset:19; MERGE-NOT: Content:
17; MERGE-NEXT: Opcode: I32_CONST
18; MERGE-NEXT: Value: 1024
19; MERGE-NEXT: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
2020
21; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o21; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o
22; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE22; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE
23; SEPARATE: - Type: DATA23; SEPARATE: - Type: DATA
24; SEPARATE-NEXT: Segments:24; SEPARATE: Segments:
25; SEPARATE-NEXT: - SectionOffset: 725; SEPARATE: Content: 68656C6C6F00
26; SEPARATE-NEXT: MemoryIndex: 026; SEPARATE: Content: 676F6F6462796500
27; SEPARATE-NEXT: Offset:27; SEPARATE: Content: '776861746576657200'
28; SEPARATE-NEXT: Opcode: I32_CONST28; SEPARATE: Content: 2A000000
29; SEPARATE-NEXT: Value: 102429; SEPARATE: Content: 636F6E7374616E7400
30; SEPARATE-NEXT: Content: 68656C6C6F0030; SEPARATE: Content: 2B
31; SEPARATE-NEXT: - SectionOffset: 1931; SEPARATE-NOT: Content:
32; SEPARATE-NEXT: MemoryIndex: 0
33; SEPARATE-NEXT: Offset:
34; SEPARATE-NEXT: Opcode: I32_CONST
35; SEPARATE-NEXT: Value: 1030
36; SEPARATE-NEXT: Content: 676F6F6462796500
37; SEPARATE-NEXT: - SectionOffset: 33
38; SEPARATE-NEXT: MemoryIndex: 0
39; SEPARATE-NEXT: Offset:
40; SEPARATE-NEXT: Opcode: I32_CONST
41; SEPARATE-NEXT: Value: 1038
42; SEPARATE-NEXT: Content: '776861746576657200'
43; SEPARATE-NEXT: - SectionOffset: 48
44; SEPARATE-NEXT: MemoryIndex: 0
45; SEPARATE-NEXT: Offset:
46; SEPARATE-NEXT: Opcode: I32_CONST
47; SEPARATE-NEXT: Value: 1048
48; SEPARATE-NEXT: Content: 2A000000
deps/lld/test/wasm/debug-removed-fn.ll created+44
...@@ -0,0 +1,44 @@
1; RUN: llc -filetype=obj < %s -o %t.o
2; RUN: wasm-ld %t.o --no-entry --export=foo -o %t.wasm
3; RUN: llvm-dwarfdump -debug-line %t.wasm | FileCheck %s
4
5; CHECK: Address
6; CHECK: 0x0000000000000005
7; CHECK: 0x0000000000000000
8
9; ModuleID = 't.bc'
10target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
11target triple = "wasm32-unknown-unknown-wasm"
12
13; Function Attrs: noinline nounwind optnone
14define hidden i32 @foo() #0 !dbg !7 {
15entry:
16 ret i32 42, !dbg !11
17}
18
19; Function Attrs: noinline nounwind optnone
20define hidden i32 @bar() #0 !dbg !12 {
21entry:
22 ret i32 6, !dbg !13
23}
24
25attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
26
27!llvm.dbg.cu = !{!0}
28!llvm.module.flags = !{!3, !4, !5}
29!llvm.ident = !{!6}
30
31!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 (trunk 337293)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
32!1 = !DIFile(filename: "t.c", directory: "/d/y")
33!2 = !{}
34!3 = !{i32 2, !"Dwarf Version", i32 4}
35!4 = !{i32 2, !"Debug Info Version", i32 3}
36!5 = !{i32 1, !"wchar_size", i32 4}
37!6 = !{!"clang version 7.0.0 (trunk 337293)"}
38!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
39!8 = !DISubroutineType(types: !9)
40!9 = !{!10}
41!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
42!11 = !DILocation(line: 2, column: 3, scope: !7)
43!12 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, isLocal: false, isDefinition: true, scopeLine: 5, isOptimized: false, unit: !0, retainedNodes: !2)
44!13 = !DILocation(line: 6, column: 3, scope: !12)
deps/lld/test/wasm/debuginfo.test+2-2
...@@ -43,7 +43,7 @@ CHECK-NEXT: DW_AT_name ("hi_foo.c")...@@ -43,7 +43,7 @@ CHECK-NEXT: DW_AT_name ("hi_foo.c")
4343
44CHECK: DW_TAG_variable44CHECK: DW_TAG_variable
45CHECK-NEXT: DW_AT_name ("y")45CHECK-NEXT: DW_AT_name ("y")
46CHECK-NEXT: DW_AT_type (0x00000097 "int[]")46CHECK-NEXT: DW_AT_type (0x00000097 "int[2]")
47CHECK-NEXT: DW_AT_external (true)47CHECK-NEXT: DW_AT_external (true)
48CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")48CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")
49CHECK-NEXT: DW_AT_decl_line (1)49CHECK-NEXT: DW_AT_decl_line (1)
...@@ -65,7 +65,7 @@ CHECK-NEXT: DW_AT_encoding (DW_ATE_unsigned)...@@ -65,7 +65,7 @@ CHECK-NEXT: DW_AT_encoding (DW_ATE_unsigned)
6565
66CHECK: DW_TAG_variable66CHECK: DW_TAG_variable
67CHECK-NEXT: DW_AT_name ("z")67CHECK-NEXT: DW_AT_name ("z")
68CHECK-NEXT: DW_AT_type (0x00000097 "int[]")68CHECK-NEXT: DW_AT_type (0x00000097 "int[2]")
69CHECK-NEXT: DW_AT_external (true)69CHECK-NEXT: DW_AT_external (true)
70CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")70CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")
71CHECK-NEXT: DW_AT_decl_line (8)71CHECK-NEXT: DW_AT_decl_line (8)
deps/lld/test/wasm/demangle.ll+8-6
...@@ -1,17 +1,19 @@...@@ -1,17 +1,19 @@
1; RUN: llc -filetype=obj %s -o %t.o1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: not wasm-ld --undefined _Z3fooi \2; RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s
3; RUN: -o %t.wasm %t.o 2>&1 | FileCheck %s
43
5; CHECK: error: undefined symbol: foo(int)4; CHECK: error: {{.*}}.o: undefined symbol: foo(int)
65
7; RUN: not wasm-ld --no-demangle --undefined _Z3fooi \6; RUN: not wasm-ld --no-demangle \
8; RUN: -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s7; RUN: -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s
98
10; CHECK-NODEMANGLE: error: undefined symbol: _Z3fooi9; CHECK-NODEMANGLE: error: {{.*}}.o: undefined symbol: _Z3fooi
1110
12target triple = "wasm32-unknown-unknown"11target triple = "wasm32-unknown-unknown"
1312
13declare void @_Z3fooi(i32);
14
14define hidden void @_start() local_unnamed_addr {15define hidden void @_start() local_unnamed_addr {
15entry:16entry:
17 call void @_Z3fooi(i32 1)
16 ret void18 ret void
17}19}
deps/lld/test/wasm/event-section.ll created+34
...@@ -0,0 +1,34 @@
1; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %p/Inputs/event-section1.ll -o %t1.o
2; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %p/Inputs/event-section2.ll -o %t2.o
3; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %s -o %t.o
4; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o
5; RUN: obj2yaml %t.wasm | FileCheck %s
6
7target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
8target triple = "wasm32-unknown-unknown"
9
10declare void @foo(i8*)
11declare void @bar(i8*)
12
13define void @_start() {
14 call void @foo(i8* null)
15 call void @bar(i8* null)
16 ret void
17}
18
19; CHECK: Sections:
20; CHECK-NEXT: - Type: TYPE
21; CHECK-NEXT: Signatures:
22; CHECK-NEXT: - Index: 0
23; CHECK-NEXT: ReturnType: NORESULT
24; CHECK-NEXT: ParamTypes: []
25; CHECK-NEXT: - Index: 1
26; CHECK-NEXT: ReturnType: NORESULT
27; CHECK-NEXT: ParamTypes:
28; CHECK-NEXT: - I32
29
30; CHECK: - Type: EVENT
31; CHECK-NEXT: Events:
32; CHECK-NEXT: - Index: 0
33; CHECK-NEXT: Attribute: 0
34; CHECK-NEXT: SigIndex: 1
deps/lld/test/wasm/export-all.ll+1-1
...@@ -42,7 +42,7 @@ entry:...@@ -42,7 +42,7 @@ entry:
42; CHECK-NOT: - Name: internal_func42; CHECK-NOT: - Name: internal_func
4343
44; EXPORT: - Type: EXPORT44; EXPORT: - Type: EXPORT
45; EXPORT: - Name: _start
46; EXPORT: - Name: bar45; EXPORT: - Name: bar
47; EXPORT: - Name: foo46; EXPORT: - Name: foo
47; EXPORT: - Name: _start
48; EXPORT-NOT: - Name: internal_func48; EXPORT-NOT: - Name: internal_func
deps/lld/test/wasm/export-table.test+1-1
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
66
7# CHECK: - Type: TABLE7# CHECK: - Type: TABLE
8# CHECK-NEXT: Tables:8# CHECK-NEXT: Tables:
9# CHECK-NEXT: - ElemType: ANYFUNC9# CHECK-NEXT: - ElemType: FUNCREF
10# CHECK-NEXT: Limits:10# CHECK-NEXT: Limits:
11# CHECK-NEXT: Flags: [ HAS_MAX ]11# CHECK-NEXT: Flags: [ HAS_MAX ]
12# CHECK-NEXT: Initial: 0x0000000112# CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/export.ll+3-3
...@@ -28,10 +28,10 @@ entry:...@@ -28,10 +28,10 @@ entry:
28; CHECK-NEXT: - Name: __data_end28; CHECK-NEXT: - Name: __data_end
29; CHECK-NEXT: Kind: GLOBAL29; CHECK-NEXT: Kind: GLOBAL
30; CHECK-NEXT: Index: 230; CHECK-NEXT: Index: 2
31; CHECK-NEXT: - Name: _start
32; CHECK-NEXT: Kind: FUNCTION
33; CHECK-NEXT: Index: 2
34; CHECK-NEXT: - Name: hidden_function31; CHECK-NEXT: - Name: hidden_function
35; CHECK-NEXT: Kind: FUNCTION32; CHECK-NEXT: Kind: FUNCTION
36; CHECK-NEXT: Index: 133; CHECK-NEXT: Index: 1
34; CHECK-NEXT: - Name: _start
35; CHECK-NEXT: Kind: FUNCTION
36; CHECK-NEXT: Index: 2
37; CHECK-NEXT: - Type: CODE37; CHECK-NEXT: - Type: CODE
deps/lld/test/wasm/import-memory.test+17
...@@ -31,3 +31,20 @@...@@ -31,3 +31,20 @@
31# CHECK-MAX-NEXT: Initial: 0x0000000431# CHECK-MAX-NEXT: Initial: 0x00000004
32# CHECK-MAX-NEXT: Maximum: 0x0000000532# CHECK-MAX-NEXT: Maximum: 0x00000005
33# CHECK-MAX-NEXT: - Type:33# CHECK-MAX-NEXT: - Type:
34
35# RUN: wasm-ld --import-memory --shared-memory --initial-memory=262144 \
36# RUN: --max-memory=327680 -o %t.max.wasm %t.start.o
37# RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-SHARED %s
38
39# Verify the --shared-memory flag works with imports
40
41# CHECK-SHARED: - Type: IMPORT
42# CHECK-SHARED-NEXT: Imports:
43# CHECK-SHARED-NEXT: - Module: env
44# CHECK-SHARED-NEXT: Field: memory
45# CHECK-SHARED-NEXT: Kind: MEMORY
46# CHECK-SHARED-NEXT: Memory:
47# CHECK-SHARED-NEXT: Flags: [ HAS_MAX, IS_SHARED ]
48# CHECK-SHARED-NEXT: Initial: 0x00000004
49# CHECK-SHARED-NEXT: Maximum: 0x00000005
50# CHECK-SHARED-NEXT: - Type:
deps/lld/test/wasm/import-table.test+1-3
...@@ -10,9 +10,7 @@...@@ -10,9 +10,7 @@
10# CHECK-NEXT: Field: __indirect_function_table10# CHECK-NEXT: Field: __indirect_function_table
11# CHECK-NEXT: Kind: TABLE11# CHECK-NEXT: Kind: TABLE
12# CHECK-NEXT: Table:12# CHECK-NEXT: Table:
13# CHECK-NEXT: ElemType: ANYFUNC13# CHECK-NEXT: ElemType: FUNCREF
14# CHECK-NEXT: Limits:14# CHECK-NEXT: Limits:
15# CHECK-NEXT: Flags: [ HAS_MAX ]
16# CHECK-NEXT: Initial: 0x0000000115# CHECK-NEXT: Initial: 0x00000001
17# CHECK-NEXT: Maximum: 0x00000001
1816
deps/lld/test/wasm/load-undefined.test+6-8
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4; RUN: llc -filetype=obj %S/Inputs/ret64.ll -o %t.o4; RUN: llc -filetype=obj %S/Inputs/ret64.ll -o %t.o
5; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t2.o5; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t2.o
6; RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.start.o6; RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.start.o
7; RUN: rm -f %t2.a
7; RUN: llvm-ar rcs %t2.a %t2.o8; RUN: llvm-ar rcs %t2.a %t2.o
8; RUN: wasm-ld %t.start.o --no-gc-sections %t2.a %t.o -o %t.wasm -u ret32 --undefined ret649; RUN: wasm-ld %t.start.o --no-gc-sections %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64
9; RUN: obj2yaml %t.wasm | FileCheck %s10; RUN: obj2yaml %t.wasm | FileCheck %s
...@@ -17,9 +18,9 @@...@@ -17,9 +18,9 @@
17; CHECK-NEXT: - Index: 118; CHECK-NEXT: - Index: 1
18; CHECK-NEXT: Name: _start19; CHECK-NEXT: Name: _start
19; CHECK-NEXT: - Index: 220; CHECK-NEXT: - Index: 2
20; CHECK-NEXT: Name: ret32
21; CHECK-NEXT: - Index: 3
22; CHECK-NEXT: Name: ret6421; CHECK-NEXT: Name: ret64
22; CHECK-NEXT: - Index: 3
23; CHECK-NEXT: Name: ret32
23; CHECK-NEXT: ...24; CHECK-NEXT: ...
2425
25; NO-LOAD: Name: name26; NO-LOAD: Name: name
...@@ -32,9 +33,6 @@...@@ -32,9 +33,6 @@
32; NO-LOAD-NEXT: Name: ret6433; NO-LOAD-NEXT: Name: ret64
33; NO-LOAD-NEXT: ...34; NO-LOAD-NEXT: ...
3435
35; Verify that referencing a symbol that doesn't exist won't work36; Verify that referencing a symbol that is not found doesn't result in a link
36; RUN: not wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s37; failure. This matches the behaviour of the ELF linker.
37; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist38; RUN: wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist
38
39; RUN: not wasm-ld %t.start.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s
40; CHECK-UNDEFINED2: symbol forced with --undefined not found: symboldoesnotexist
deps/lld/test/wasm/local-symbols.ll+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1; Test that internal symbols can still be GC'd when with --export-dynamic.
1; RUN: llc -filetype=obj %s -o %t.o2; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld -o %t.wasm %t.o3; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o
3; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
45
5target triple = "wasm32-unknown-unknown"6target triple = "wasm32-unknown-unknown"
...@@ -35,7 +36,7 @@ entry:...@@ -35,7 +36,7 @@ entry:
35; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]36; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]
36; CHECK-NEXT: - Type: TABLE37; CHECK-NEXT: - Type: TABLE
37; CHECK-NEXT: Tables:38; CHECK-NEXT: Tables:
38; CHECK-NEXT: - ElemType: ANYFUNC39; CHECK-NEXT: - ElemType: FUNCREF
39; CHECK-NEXT: Limits:40; CHECK-NEXT: Limits:
40; CHECK-NEXT: Flags: [ HAS_MAX ]41; CHECK-NEXT: Flags: [ HAS_MAX ]
41; CHECK-NEXT: Initial: 0x0000000142; CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/locals-duplicate.test+7-7
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1; RUN: llc -filetype=obj %p/Inputs/locals-duplicate1.ll -o %t1.o1; RUN: llc -filetype=obj %p/Inputs/locals-duplicate1.ll -o %t1.o
2; RUN: llc -filetype=obj %p/Inputs/locals-duplicate2.ll -o %t2.o2; RUN: llc -filetype=obj %p/Inputs/locals-duplicate2.ll -o %t2.o
3; RUN: wasm-ld --no-entry -o %t.wasm %t1.o %t2.o3; RUN: wasm-ld --export-dynamic --no-entry -o %t.wasm %t1.o %t2.o
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55
6; CHECK: --- !WASM6; CHECK: --- !WASM
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20; CHECK-NEXT: 1, 1, 1 ]20; CHECK-NEXT: 1, 1, 1 ]
21; CHECK-NEXT: - Type: TABLE21; CHECK-NEXT: - Type: TABLE
22; CHECK-NEXT: Tables:22; CHECK-NEXT: Tables:
23; CHECK-NEXT: - ElemType: ANYFUNC23; CHECK-NEXT: - ElemType: FUNCREF
24; CHECK-NEXT: Limits:24; CHECK-NEXT: Limits:
25; CHECK-NEXT: Flags: [ HAS_MAX ]25; CHECK-NEXT: Flags: [ HAS_MAX ]
26; CHECK-NEXT: Initial: 0x0000000726; CHECK-NEXT: Initial: 0x00000007
...@@ -253,7 +253,7 @@...@@ -253,7 +253,7 @@
253; RELOC-NEXT: 0, 0 ]253; RELOC-NEXT: 0, 0 ]
254; RELOC-NEXT: - Type: TABLE254; RELOC-NEXT: - Type: TABLE
255; RELOC-NEXT: Tables:255; RELOC-NEXT: Tables:
256; RELOC-NEXT: - ElemType: ANYFUNC256; RELOC-NEXT: - ElemType: FUNCREF
257; RELOC-NEXT: Limits:257; RELOC-NEXT: Limits:
258; RELOC-NEXT: Flags: [ HAS_MAX ]258; RELOC-NEXT: Flags: [ HAS_MAX ]
259; RELOC-NEXT: Initial: 0x00000007259; RELOC-NEXT: Initial: 0x00000007
...@@ -382,7 +382,7 @@...@@ -382,7 +382,7 @@
382; RELOC-NEXT: Content: '0000000000000000'382; RELOC-NEXT: Content: '0000000000000000'
383; RELOC-NEXT: - Type: CUSTOM383; RELOC-NEXT: - Type: CUSTOM
384; RELOC-NEXT: Name: linking384; RELOC-NEXT: Name: linking
385; RELOC-NEXT: Version: 1385; RELOC-NEXT: Version: 2
386; RELOC-NEXT: SymbolTable:386; RELOC-NEXT: SymbolTable:
387; RELOC-NEXT: - Index: 0387; RELOC-NEXT: - Index: 0
388; RELOC-NEXT: Kind: FUNCTION388; RELOC-NEXT: Kind: FUNCTION
...@@ -516,15 +516,15 @@...@@ -516,15 +516,15 @@
516; RELOC-NEXT: SegmentInfo:516; RELOC-NEXT: SegmentInfo:
517; RELOC-NEXT: - Index: 0517; RELOC-NEXT: - Index: 0
518; RELOC-NEXT: Name: .bss.colliding_global1518; RELOC-NEXT: Name: .bss.colliding_global1
519; RELOC-NEXT: Alignment: 4519; RELOC-NEXT: Alignment: 2
520; RELOC-NEXT: Flags: [ ]520; RELOC-NEXT: Flags: [ ]
521; RELOC-NEXT: - Index: 1521; RELOC-NEXT: - Index: 1
522; RELOC-NEXT: Name: .bss.colliding_global2522; RELOC-NEXT: Name: .bss.colliding_global2
523; RELOC-NEXT: Alignment: 4523; RELOC-NEXT: Alignment: 2
524; RELOC-NEXT: Flags: [ ]524; RELOC-NEXT: Flags: [ ]
525; RELOC-NEXT: - Index: 2525; RELOC-NEXT: - Index: 2
526; RELOC-NEXT: Name: .bss.colliding_global3526; RELOC-NEXT: Name: .bss.colliding_global3
527; RELOC-NEXT: Alignment: 4527; RELOC-NEXT: Alignment: 2
528; RELOC-NEXT: Flags: [ ]528; RELOC-NEXT: Flags: [ ]
529; RELOC-NEXT: - Type: CUSTOM529; RELOC-NEXT: - Type: CUSTOM
530; RELOC-NEXT: Name: name530; RELOC-NEXT: Name: name
deps/lld/test/wasm/lto/archive.ll+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2; RUN: rm -f %t.a2; RUN: rm -f %t.a
3; RUN: llvm-ar rcs %t.a %t1.o3; RUN: llvm-ar rcs %t.a %t1.o
4; RUN: llvm-as %s -o %t2.o4; RUN: llvm-as %s -o %t2.o
5; RUN: wasm-ld %t2.o %t.a -o %t35; RUN: wasm-ld --export-dynamic %t2.o %t.a -o %t3
6; RUN: obj2yaml %t3 | FileCheck %s6; RUN: obj2yaml %t3 | FileCheck %s
77
8target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"8target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
deps/lld/test/wasm/lto/cache.ll+6
...@@ -1,5 +1,7 @@...@@ -1,5 +1,7 @@
1; RUN: opt -module-hash -module-summary %s -o %t.o1; RUN: opt -module-hash -module-summary %s -o %t.o
2; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o2; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o
3; NetBSD: noatime mounts currently inhibit 'touch' from updating atime
4; UNSUPPORTED: system-netbsd
35
4; RUN: rm -Rf %t.cache && mkdir %t.cache6; RUN: rm -Rf %t.cache && mkdir %t.cache
5; Create two files that would be removed by cache pruning due to age.7; Create two files that would be removed by cache pruning due to age.
...@@ -17,6 +19,10 @@...@@ -17,6 +19,10 @@
17; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t.wasm %t2.o %t.o19; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t.wasm %t2.o %t.o
18; RUN: ls %t.cache | count 520; RUN: ls %t.cache | count 5
1921
22; Increase the age of llvmcache-foo, which will give it the oldest time stamp
23; so that it is processed and removed first.
24; RUN: %python -c 'import os,sys,time; t=time.time()-120; os.utime(sys.argv[1],(t,t))' %t.cache/llvmcache-foo
25
20; This should remove it.26; This should remove it.
21; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t.wasm %t2.o %t.o27; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t.wasm %t2.o %t.o
22; RUN: ls %t.cache | count 428; RUN: ls %t.cache | count 4
deps/lld/test/wasm/lto/export.ll+3-3
...@@ -29,10 +29,10 @@ entry:...@@ -29,10 +29,10 @@ entry:
29; CHECK-NEXT: - Name: __data_end29; CHECK-NEXT: - Name: __data_end
30; CHECK-NEXT: Kind: GLOBAL30; CHECK-NEXT: Kind: GLOBAL
31; CHECK-NEXT: Index: 231; CHECK-NEXT: Index: 2
32; CHECK-NEXT: - Name: _start
33; CHECK-NEXT: Kind: FUNCTION
34; CHECK-NEXT: Index: 2
35; CHECK-NEXT: - Name: hidden_function32; CHECK-NEXT: - Name: hidden_function
36; CHECK-NEXT: Kind: FUNCTION33; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 134; CHECK-NEXT: Index: 1
35; CHECK-NEXT: - Name: _start
36; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 2
38; CHECK-NEXT: - Type: CODE38; CHECK-NEXT: - Type: CODE
deps/lld/test/wasm/lto/signature-mismatch.ll created+19
...@@ -0,0 +1,19 @@
1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
3; RUN: not wasm-ld --fatal-warnings %t.o %t1.o -o %t.wasm 2>&1 | FileCheck %s
4
5; Test that functions defined in bitcode correctly report signature
6; mistmaches with existing undefined sybmols in normal objects.
7
8target triple = "wasm32-unknown-unknown"
9
10; f is defined to take no argument in archive.ll which is compiled to bitcode
11declare void @f(i32);
12
13define void @_start() {
14 call void @f(i32 0)
15 ret void
16}
17
18; CHECK: >>> defined as (i32) -> void in {{.*}}signature-mismatch.ll.tmp1.o
19; CHECK: >>> defined as () -> void in lto.tmp
deps/lld/test/wasm/many-functions.ll+3-3
...@@ -815,7 +815,7 @@ entry:...@@ -815,7 +815,7 @@ entry:
815; CHECK-NEXT: Content: '01000000'815; CHECK-NEXT: Content: '01000000'
816; CHECK-NEXT: - Type: CUSTOM816; CHECK-NEXT: - Type: CUSTOM
817; CHECK-NEXT: Name: linking817; CHECK-NEXT: Name: linking
818; CHECK-NEXT: Version: 1818; CHECK-NEXT: Version: 2
819; CHECK-NEXT: SymbolTable:819; CHECK-NEXT: SymbolTable:
820; CHECK-NEXT: - Index: 0820; CHECK-NEXT: - Index: 0
821; CHECK-NEXT: Kind: FUNCTION821; CHECK-NEXT: Kind: FUNCTION
...@@ -1482,9 +1482,9 @@ entry:...@@ -1482,9 +1482,9 @@ entry:
1482; CHECK-NEXT: SegmentInfo:1482; CHECK-NEXT: SegmentInfo:
1483; CHECK-NEXT: - Index: 01483; CHECK-NEXT: - Index: 0
1484; CHECK-NEXT: Name: .data.g01484; CHECK-NEXT: Name: .data.g0
1485; CHECK-NEXT: Alignment: 41485; CHECK-NEXT: Alignment: 2
1486; CHECK-NEXT: Flags: [ ]1486; CHECK-NEXT: Flags: [ ]
1487; CHECK-NEXT: - Index: 11487; CHECK-NEXT: - Index: 1
1488; CHECK-NEXT: Name: .data.foo1488; CHECK-NEXT: Name: .data.foo
1489; CHECK-NEXT: Alignment: 41489; CHECK-NEXT: Alignment: 2
1490; CHECK-NEXT: Flags: [ ]1490; CHECK-NEXT: Flags: [ ]
deps/lld/test/wasm/relocatable.ll+8-8
...@@ -63,7 +63,7 @@ entry:...@@ -63,7 +63,7 @@ entry:
63; CHECK-NEXT: FunctionTypes: [ 2, 1, 1 ]63; CHECK-NEXT: FunctionTypes: [ 2, 1, 1 ]
64; CHECK-NEXT: - Type: TABLE64; CHECK-NEXT: - Type: TABLE
65; CHECK-NEXT: Tables:65; CHECK-NEXT: Tables:
66; CHECK-NEXT: - ElemType: ANYFUNC66; CHECK-NEXT: - ElemType: FUNCREF
67; CHECK-NEXT: Limits:67; CHECK-NEXT: Limits:
68; CHECK-NEXT: Flags: [ HAS_MAX ]68; CHECK-NEXT: Flags: [ HAS_MAX ]
69; CHECK-NEXT: Initial: 0x0000000469; CHECK-NEXT: Initial: 0x00000004
...@@ -157,7 +157,7 @@ entry:...@@ -157,7 +157,7 @@ entry:
157; CHECK-NEXT: Content: '616263'157; CHECK-NEXT: Content: '616263'
158; CHECK-NEXT: - Type: CUSTOM158; CHECK-NEXT: - Type: CUSTOM
159; CHECK-NEXT: Name: linking159; CHECK-NEXT: Name: linking
160; CHECK-NEXT: Version: 1160; CHECK-NEXT: Version: 2
161; CHECK-NEXT: SymbolTable:161; CHECK-NEXT: SymbolTable:
162; CHECK-NEXT: - Index: 0162; CHECK-NEXT: - Index: 0
163; CHECK-NEXT: Kind: FUNCTION163; CHECK-NEXT: Kind: FUNCTION
...@@ -232,27 +232,27 @@ entry:...@@ -232,27 +232,27 @@ entry:
232; CHECK-NEXT: SegmentInfo:232; CHECK-NEXT: SegmentInfo:
233; CHECK-NEXT: - Index: 0233; CHECK-NEXT: - Index: 0
234; CHECK-NEXT: Name: .rodata.hello_str234; CHECK-NEXT: Name: .rodata.hello_str
235; CHECK-NEXT: Alignment: 1235; CHECK-NEXT: Alignment: 0
236; CHECK-NEXT: Flags: [ ]236; CHECK-NEXT: Flags: [ ]
237; CHECK-NEXT: - Index: 1237; CHECK-NEXT: - Index: 1
238; CHECK-NEXT: Name: .data.func_addr1238; CHECK-NEXT: Name: .data.func_addr1
239; CHECK-NEXT: Alignment: 4239; CHECK-NEXT: Alignment: 2
240; CHECK-NEXT: Flags: [ ]240; CHECK-NEXT: Flags: [ ]
241; CHECK-NEXT: - Index: 2241; CHECK-NEXT: - Index: 2
242; CHECK-NEXT: Name: .data.func_addr2242; CHECK-NEXT: Name: .data.func_addr2
243; CHECK-NEXT: Alignment: 4243; CHECK-NEXT: Alignment: 2
244; CHECK-NEXT: Flags: [ ]244; CHECK-NEXT: Flags: [ ]
245; CHECK-NEXT: - Index: 3245; CHECK-NEXT: - Index: 3
246; CHECK-NEXT: Name: .data.func_addr3246; CHECK-NEXT: Name: .data.func_addr3
247; CHECK-NEXT: Alignment: 4247; CHECK-NEXT: Alignment: 2
248; CHECK-NEXT: Flags: [ ]248; CHECK-NEXT: Flags: [ ]
249; CHECK-NEXT: - Index: 4249; CHECK-NEXT: - Index: 4
250; CHECK-NEXT: Name: .data.data_addr1250; CHECK-NEXT: Name: .data.data_addr1
251; CHECK-NEXT: Alignment: 8251; CHECK-NEXT: Alignment: 3
252; CHECK-NEXT: Flags: [ ]252; CHECK-NEXT: Flags: [ ]
253; CHECK-NEXT: - Index: 5253; CHECK-NEXT: - Index: 5
254; CHECK-NEXT: Name: .rodata.data_comdat254; CHECK-NEXT: Name: .rodata.data_comdat
255; CHECK-NEXT: Alignment: 1255; CHECK-NEXT: Alignment: 0
256; CHECK-NEXT: Flags: [ ]256; CHECK-NEXT: Flags: [ ]
257; CHECK-NEXT: Comdats:257; CHECK-NEXT: Comdats:
258; CHECK-NEXT: - Name: func_comdat258; CHECK-NEXT: - Name: func_comdat
deps/lld/test/wasm/shared.ll created+82
...@@ -0,0 +1,82 @@
1; RUN: llc -O0 -filetype=obj %s -o %t.o
2; RUN: wasm-ld -shared -o %t.wasm %t.o
3; RUN: obj2yaml %t.wasm | FileCheck %s
4
5target triple = "wasm32-unknown-unknown"
6
7@data = hidden global i32 2, align 4
8@indirect_func = local_unnamed_addr global void ()* @foo, align 4
9@indirect_func_external = local_unnamed_addr global void ()* @func_external, align 4
10
11define default void @foo() {
12entry:
13 ; To ensure we use __stack_pointer
14 %ptr = alloca i32
15 %0 = load i32, i32* @data, align 4
16 %1 = load i32, i32* @data_external, align 4
17 %2 = load void ()*, void ()** @indirect_func, align 4
18 call void %2()
19 ret void
20}
21
22declare void @func_external()
23
24@data_external = external global i32
25
26
27; check for dylink section at start
28
29; CHECK: Sections:
30; CHECK-NEXT: - Type: CUSTOM
31; CHECK-NEXT: Name: dylink
32; CHECK-NEXT: MemorySize: 8
33; CHECK-NEXT: MemoryAlignment: 2
34; CHECK-NEXT: TableSize: 2
35; CHECK-NEXT: TableAlignment: 0
36
37; check for import of __table_base and __memory_base globals
38
39; CHECK: - Type: IMPORT
40; CHECK-NEXT: Imports:
41; CHECK-NEXT: - Module: env
42; CHECK-NEXT: Field: __indirect_function_table
43; CHECK-NEXT: Kind: TABLE
44; CHECK-NEXT: Table:
45; CHECK-NEXT: ElemType: FUNCREF
46; CHECK-NEXT: Limits:
47; CHECK-NEXT: Initial: 0x00000002
48; CHECK-NEXT: - Module: env
49; CHECK-NEXT: Field: __stack_pointer
50; CHECK-NEXT: Kind: GLOBAL
51; CHECK-NEXT: GlobalType: I32
52; CHECK-NEXT: GlobalMutable: true
53; CHECK-NEXT: - Module: env
54; CHECK-NEXT: Field: __memory_base
55; CHECK-NEXT: Kind: GLOBAL
56; CHECK-NEXT: GlobalType: I32
57; CHECK-NEXT: GlobalMutable: false
58; CHECK-NEXT: - Module: env
59; CHECK-NEXT: Field: __table_base
60; CHECK-NEXT: Kind: GLOBAL
61; CHECK-NEXT: GlobalType: I32
62; CHECK-NEXT: GlobalMutable: false
63
64; check for elem segment initialized with __table_base global as offset
65
66; CHECK: - Type: ELEM
67; CHECK-NEXT: Segments:
68; CHECK-NEXT: - Offset:
69; CHECK-NEXT: Opcode: GLOBAL_GET
70; CHECK-NEXT: Index: 2
71; CHECK-NEXT: Functions: [ 2, 0 ]
72
73; check the data segment initialized with __memory_base global as offset
74
75; CHECK: - Type: DATA
76; CHECK-NEXT: Segments:
77; CHECK-NEXT: - SectionOffset: 6
78; CHECK-NEXT: MemoryIndex: 0
79; CHECK-NEXT: Offset:
80; CHECK-NEXT: Opcode: GLOBAL_GET
81; CHECK-NEXT: Index: 1
82; CHECK-NEXT: Content: '0000000001000000'
deps/lld/test/wasm/signature-mismatch-weak.ll+2-2
...@@ -14,5 +14,5 @@ entry:...@@ -14,5 +14,5 @@ entry:
14}14}
1515
16; CHECK: warning: function signature mismatch: weakFn16; CHECK: warning: function signature mismatch: weakFn
17; CHECK-NEXT: >>> defined as () -> I32 in {{.*}}signature-mismatch-weak.ll.tmp.o17; CHECK-NEXT: >>> defined as () -> i32 in {{.*}}signature-mismatch-weak.ll.tmp.o
18; CHECK-NEXT: >>> defined as () -> I64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o18; CHECK-NEXT: >>> defined as () -> i64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o
deps/lld/test/wasm/signature-mismatch.ll+4-4
...@@ -18,9 +18,9 @@ entry:...@@ -18,9 +18,9 @@ entry:
18declare i32 @ret32(i32, i64, i32) local_unnamed_addr #118declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
1919
20; CHECK: error: function signature mismatch: ret3220; CHECK: error: function signature mismatch: ret32
21; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o21; CHECK-NEXT: >>> defined as (i32, i64, i32) -> i32 in {{.*}}.main.o
22; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o22; CHECK-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
2323
24; REVERSE: error: function signature mismatch: ret3224; REVERSE: error: function signature mismatch: ret32
25; REVERSE-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o25; REVERSE-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
26; REVERSE-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o26; REVERSE-NEXT: >>> defined as (i32, i64, i32) -> i32 in {{.*}}.main.o
deps/lld/test/wasm/stack-pointer.ll+2-2
...@@ -31,7 +31,7 @@ entry:...@@ -31,7 +31,7 @@ entry:
31; CHECK-NEXT: FunctionTypes: [ 0 ]31; CHECK-NEXT: FunctionTypes: [ 0 ]
32; CHECK-NEXT: - Type: TABLE32; CHECK-NEXT: - Type: TABLE
33; CHECK-NEXT: Tables:33; CHECK-NEXT: Tables:
34; CHECK-NEXT: - ElemType: ANYFUNC34; CHECK-NEXT: - ElemType: FUNCREF
35; CHECK-NEXT: Limits:35; CHECK-NEXT: Limits:
36; CHECK-NEXT: Flags: [ HAS_MAX ]36; CHECK-NEXT: Flags: [ HAS_MAX ]
37; CHECK-NEXT: Initial: 0x0000000137; CHECK-NEXT: Initial: 0x00000001
...@@ -50,7 +50,7 @@ entry:...@@ -50,7 +50,7 @@ entry:
50; CHECK-NEXT: Body: 23808080800041106B1A41000B50; CHECK-NEXT: Body: 23808080800041106B1A41000B
51; CHECK-NEXT: - Type: CUSTOM51; CHECK-NEXT: - Type: CUSTOM
52; CHECK-NEXT: Name: linking52; CHECK-NEXT: Name: linking
53; CHECK-NEXT: Version: 153; CHECK-NEXT: Version: 2
54; CHECK-NEXT: SymbolTable:54; CHECK-NEXT: SymbolTable:
55; CHECK-NEXT: - Index: 055; CHECK-NEXT: - Index: 0
56; CHECK-NEXT: Kind: FUNCTION56; CHECK-NEXT: Kind: FUNCTION
deps/lld/test/wasm/strip-all.test created+10
...@@ -0,0 +1,10 @@
1RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
2RUN: wasm-ld --strip-all -o %t.wasm %t.start.o
3RUN: obj2yaml %t.wasm | FileCheck %s
4
5# Test alias -s
6RUN: wasm-ld -s -o %t.wasm %t.start.o
7RUN: obj2yaml %t.wasm | FileCheck %s
8
9# Check that there is no name section
10CHECK-NOT: Name: name
deps/lld/test/wasm/strip-debug.test+4
...@@ -2,5 +2,9 @@ RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o...@@ -2,5 +2,9 @@ RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
2RUN: wasm-ld --strip-debug -o %t.wasm %t.start.o2RUN: wasm-ld --strip-debug -o %t.wasm %t.start.o
3RUN: obj2yaml %t.wasm | FileCheck %s3RUN: obj2yaml %t.wasm | FileCheck %s
44
5# Test alias -S
6RUN: wasm-ld -S -o %t.wasm %t.start.o
7RUN: obj2yaml %t.wasm | FileCheck %s
8
5# Check that there is no name section9# Check that there is no name section
6CHECK-NOT: Name: name10CHECK-NOT: Name: name
deps/lld/test/wasm/undefined-entry.test+3-5
...@@ -1,11 +1,9 @@...@@ -1,11 +1,9 @@
1RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o1RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
2RUN: not wasm-ld -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s2RUN: not wasm-ld -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
3RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
3RUN: not wasm-ld -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM4RUN: not wasm-ld -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM
4RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-ALLOW
55
6CHECK: error: undefined symbol: _start6CHECK: error: entry symbol not defined (pass --no-entry to supress): _start
7CHECK-CUSTOM: error: undefined symbol: foo7CHECK-CUSTOM: error: entry symbol not defined (pass --no-entry to supress): foo
8CHECK-ALLOW: error: entry symbol not defined (pass --no-entry to supress):
9_start
108
11RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o9RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o
deps/lld/test/wasm/undefined-weak-call.ll+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1; RUN: llc -filetype=obj %s -o %t.o1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld --no-entry --print-gc-sections %t.o \2; RUN: wasm-ld --entry=callWeakFuncs --print-gc-sections %t.o \
3; RUN: -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s3; RUN: -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55
...@@ -45,7 +45,7 @@ define i32 @callWeakFuncs() {...@@ -45,7 +45,7 @@ define i32 @callWeakFuncs() {
45; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ]45; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ]
46; CHECK-NEXT: - Type: TABLE46; CHECK-NEXT: - Type: TABLE
47; CHECK-NEXT: Tables:47; CHECK-NEXT: Tables:
48; CHECK-NEXT: - ElemType: ANYFUNC48; CHECK-NEXT: - ElemType: FUNCREF
49; CHECK-NEXT: Limits:49; CHECK-NEXT: Limits:
50; CHECK-NEXT: Flags: [ HAS_MAX ]50; CHECK-NEXT: Flags: [ HAS_MAX ]
51; CHECK-NEXT: Initial: 0x0000000151; CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/undefined.ll+2-2
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1; RUN: llc -filetype=obj %s -o %t.o1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o2; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
33
4; Fails due to undefined 'foo' and also 'baz'4; Fails due to undefined 'foo'
5; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s5; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s
6; CHECK: error: {{.*}}.o: undefined symbol: foo6; CHECK: error: {{.*}}.o: undefined symbol: foo
7; CHECK: error: undefined symbol: baz7; CHECK-NOT: undefined symbol: baz
88
9; Succeeds if we pass a file containing 'foo' as --allow-undefined-file.9; Succeeds if we pass a file containing 'foo' as --allow-undefined-file.
10; RUN: echo 'foo' > %t.txt10; RUN: echo 'foo' > %t.txt
deps/lld/test/wasm/visibility-hidden.ll+30-6
...@@ -1,11 +1,18 @@...@@ -1,11 +1,18 @@
1; RUN: llc -filetype=obj -o %t.o %s1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o2; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o
3; RUN: rm -f %t2.a
3; RUN: llvm-ar rcs %t2.a %t2.o4; RUN: llvm-ar rcs %t2.a %t2.o
4; RUN: wasm-ld %t.o %t2.a -o %t.wasm5
6; Test that symbols with hidden visitiblity are not export, even with
7; --export-dynamic
8; RUN: wasm-ld --export-dynamic %t.o %t2.a -o %t.wasm
5; RUN: obj2yaml %t.wasm | FileCheck %s9; RUN: obj2yaml %t.wasm | FileCheck %s
610
7; Test that hidden symbols are not exported, whether pulled in from an archive11; Test that symbols with default visitiblity are not exported without
8; or directly.12; --export-dynamic
13; RUN: wasm-ld %t.o %t2.a -o %t.nodef.wasm
14; RUN: obj2yaml %t.nodef.wasm | FileCheck %s -check-prefix=NO-DEFAULT
15
916
10target triple = "wasm32-unknown-unknown"17target triple = "wasm32-unknown-unknown"
1118
...@@ -42,13 +49,30 @@ entry:...@@ -42,13 +49,30 @@ entry:
42; CHECK-NEXT: - Name: __data_end49; CHECK-NEXT: - Name: __data_end
43; CHECK-NEXT: Kind: GLOBAL50; CHECK-NEXT: Kind: GLOBAL
44; CHECK-NEXT: Index: 251; CHECK-NEXT: Index: 2
45; CHECK-NEXT: - Name: _start
46; CHECK-NEXT: Kind: FUNCTION
47; CHECK-NEXT: Index: 3
48; CHECK-NEXT: - Name: objectDefault52; CHECK-NEXT: - Name: objectDefault
49; CHECK-NEXT: Kind: FUNCTION53; CHECK-NEXT: Kind: FUNCTION
50; CHECK-NEXT: Index: 254; CHECK-NEXT: Index: 2
55; CHECK-NEXT: - Name: _start
56; CHECK-NEXT: Kind: FUNCTION
57; CHECK-NEXT: Index: 3
51; CHECK-NEXT: - Name: archiveDefault58; CHECK-NEXT: - Name: archiveDefault
52; CHECK-NEXT: Kind: FUNCTION59; CHECK-NEXT: Kind: FUNCTION
53; CHECK-NEXT: Index: 560; CHECK-NEXT: Index: 5
54; CHECK-NEXT: - Type:61; CHECK-NEXT: - Type:
62
63
64; NO-DEFAULT: - Type: EXPORT
65; NO-DEFAULT-NEXT: Exports:
66; NO-DEFAULT-NEXT: - Name: memory
67; NO-DEFAULT-NEXT: Kind: MEMORY
68; NO-DEFAULT-NEXT: Index: 0
69; NO-DEFAULT-NEXT: - Name: __heap_base
70; NO-DEFAULT-NEXT: Kind: GLOBAL
71; NO-DEFAULT-NEXT: Index: 1
72; NO-DEFAULT-NEXT: - Name: __data_end
73; NO-DEFAULT-NEXT: Kind: GLOBAL
74; NO-DEFAULT-NEXT: Index: 2
75; NO-DEFAULT-NEXT: - Name: _start
76; NO-DEFAULT-NEXT: Kind: FUNCTION
77; NO-DEFAULT-NEXT: Index: 3
78; NO-DEFAULT-NEXT: - Type:
deps/lld/test/wasm/weak-alias-overide.ll+5-5
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1; RUN: llc -filetype=obj -o %t.o %s1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o2; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
3; RUN: wasm-ld %t.o %t2.o -o %t.wasm3; RUN: wasm-ld --export-dynamic %t.o %t2.o -o %t.wasm
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55
6; Test that the strongly defined alias_fn from this file is used both here6; Test that the strongly defined alias_fn from this file is used both here
...@@ -35,7 +35,7 @@ entry:...@@ -35,7 +35,7 @@ entry:
35; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ]35; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ]
36; CHECK-NEXT: - Type: TABLE36; CHECK-NEXT: - Type: TABLE
37; CHECK-NEXT: Tables:37; CHECK-NEXT: Tables:
38; CHECK-NEXT: - ElemType: ANYFUNC38; CHECK-NEXT: - ElemType: FUNCREF
39; CHECK-NEXT: Limits:39; CHECK-NEXT: Limits:
40; CHECK-NEXT: Flags: [ HAS_MAX ]40; CHECK-NEXT: Flags: [ HAS_MAX ]
41; CHECK-NEXT: Initial: 0x0000000341; CHECK-NEXT: Initial: 0x00000003
...@@ -74,12 +74,12 @@ entry:...@@ -74,12 +74,12 @@ entry:
74; CHECK-NEXT: - Name: __data_end74; CHECK-NEXT: - Name: __data_end
75; CHECK-NEXT: Kind: GLOBAL75; CHECK-NEXT: Kind: GLOBAL
76; CHECK-NEXT: Index: 276; CHECK-NEXT: Index: 2
77; CHECK-NEXT: - Name: _start
78; CHECK-NEXT: Kind: FUNCTION
79; CHECK-NEXT: Index: 2
80; CHECK-NEXT: - Name: alias_fn77; CHECK-NEXT: - Name: alias_fn
81; CHECK-NEXT: Kind: FUNCTION78; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 179; CHECK-NEXT: Index: 1
80; CHECK-NEXT: - Name: _start
81; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 2
83; CHECK-NEXT: - Name: direct_fn83; CHECK-NEXT: - Name: direct_fn
84; CHECK-NEXT: Kind: FUNCTION84; CHECK-NEXT: Kind: FUNCTION
85; CHECK-NEXT: Index: 385; CHECK-NEXT: Index: 3
deps/lld/test/wasm/weak-alias.ll+4-4
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1; RUN: llc -filetype=obj -o %t.o %s1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o2; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
3; RUN: wasm-ld %t.o %t2.o -o %t.wasm3; RUN: wasm-ld --export-dynamic %t.o %t2.o -o %t.wasm
4; RUN: obj2yaml %t.wasm | FileCheck %s4; RUN: obj2yaml %t.wasm | FileCheck %s
55
6; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly6; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly
...@@ -32,7 +32,7 @@ entry:...@@ -32,7 +32,7 @@ entry:
32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1, 1 ]32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1, 1 ]
33; CHECK-NEXT: - Type: TABLE33; CHECK-NEXT: - Type: TABLE
34; CHECK-NEXT: Tables:34; CHECK-NEXT: Tables:
35; CHECK-NEXT: - ElemType: ANYFUNC35; CHECK-NEXT: - ElemType: FUNCREF
36; CHECK-NEXT: Limits:36; CHECK-NEXT: Limits:
37; CHECK-NEXT: Flags: [ HAS_MAX ]37; CHECK-NEXT: Flags: [ HAS_MAX ]
38; CHECK-NEXT: Initial: 0x0000000238; CHECK-NEXT: Initial: 0x00000002
...@@ -170,7 +170,7 @@ entry:...@@ -170,7 +170,7 @@ entry:
170; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]170; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]
171; RELOC-NEXT: - Type: TABLE171; RELOC-NEXT: - Type: TABLE
172; RELOC-NEXT: Tables:172; RELOC-NEXT: Tables:
173; RELOC-NEXT: - ElemType: ANYFUNC173; RELOC-NEXT: - ElemType: FUNCREF
174; RELOC-NEXT: Limits:174; RELOC-NEXT: Limits:
175; RELOC-NEXT: Flags: [ HAS_MAX ]175; RELOC-NEXT: Flags: [ HAS_MAX ]
176; RELOC-NEXT: Initial: 0x00000002176; RELOC-NEXT: Initial: 0x00000002
...@@ -250,7 +250,7 @@ entry:...@@ -250,7 +250,7 @@ entry:
250; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B250; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
251; RELOC-NEXT: - Type: CUSTOM251; RELOC-NEXT: - Type: CUSTOM
252; RELOC-NEXT: Name: linking252; RELOC-NEXT: Name: linking
253; RELOC-NEXT: Version: 1253; RELOC-NEXT: Version: 2
254; RELOC-NEXT: SymbolTable:254; RELOC-NEXT: SymbolTable:
255; RELOC-NEXT: - Index: 0255; RELOC-NEXT: - Index: 0
256; RELOC-NEXT: Kind: FUNCTION256; RELOC-NEXT: Kind: FUNCTION
deps/lld/test/wasm/weak-symbols.ll+6-11
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o1; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o
2; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o2; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o
3; RUN: llc -filetype=obj %s -o %t.o3; RUN: llc -filetype=obj %s -o %t.o
4; RUN: wasm-ld -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o4; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
5; RUN: obj2yaml %t.wasm | FileCheck %s5; RUN: obj2yaml %t.wasm | FileCheck %s
66
7target triple = "wasm32-unknown-unknown"7target triple = "wasm32-unknown-unknown"
...@@ -29,10 +29,10 @@ entry:...@@ -29,10 +29,10 @@ entry:
29; CHECK-NEXT: ReturnType: I3229; CHECK-NEXT: ReturnType: I32
30; CHECK-NEXT: ParamTypes:30; CHECK-NEXT: ParamTypes:
31; CHECK-NEXT: - Type: FUNCTION31; CHECK-NEXT: - Type: FUNCTION
32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1 ]32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1 ]
33; CHECK-NEXT: - Type: TABLE33; CHECK-NEXT: - Type: TABLE
34; CHECK-NEXT: Tables:34; CHECK-NEXT: Tables:
35; CHECK-NEXT: - ElemType: ANYFUNC35; CHECK-NEXT: - ElemType: FUNCREF
36; CHECK-NEXT: Limits:36; CHECK-NEXT: Limits:
37; CHECK-NEXT: Flags: [ HAS_MAX ]37; CHECK-NEXT: Flags: [ HAS_MAX ]
38; CHECK-NEXT: Initial: 0x0000000238; CHECK-NEXT: Initial: 0x00000002
...@@ -59,7 +59,7 @@ entry:...@@ -59,7 +59,7 @@ entry:
59; CHECK-NEXT: Mutable: false59; CHECK-NEXT: Mutable: false
60; CHECK-NEXT: InitExpr:60; CHECK-NEXT: InitExpr:
61; CHECK-NEXT: Opcode: I32_CONST61; CHECK-NEXT: Opcode: I32_CONST
62; CHECK-NEXT: Value: 103262; CHECK-NEXT: Value: 1028
63; CHECK-NEXT: - Index: 363; CHECK-NEXT: - Index: 3
64; CHECK-NEXT: Type: I3264; CHECK-NEXT: Type: I32
65; CHECK-NEXT: Mutable: false65; CHECK-NEXT: Mutable: false
...@@ -91,7 +91,7 @@ entry:...@@ -91,7 +91,7 @@ entry:
91; CHECK-NEXT: Index: 391; CHECK-NEXT: Index: 3
92; CHECK-NEXT: - Name: exportWeak292; CHECK-NEXT: - Name: exportWeak2
93; CHECK-NEXT: Kind: FUNCTION93; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 594; CHECK-NEXT: Index: 4
95; CHECK-NEXT: - Type: ELEM95; CHECK-NEXT: - Type: ELEM
96; CHECK-NEXT: Segments:96; CHECK-NEXT: Segments:
97; CHECK-NEXT: - Offset:97; CHECK-NEXT: - Offset:
...@@ -114,9 +114,6 @@ entry:...@@ -114,9 +114,6 @@ entry:
114; CHECK-NEXT: Body: 4181808080000B114; CHECK-NEXT: Body: 4181808080000B
115; CHECK-NEXT: - Index: 4115; CHECK-NEXT: - Index: 4
116; CHECK-NEXT: Locals:116; CHECK-NEXT: Locals:
117; CHECK-NEXT: Body: 41020B
118; CHECK-NEXT: - Index: 5
119; CHECK-NEXT: Locals:
120; CHECK-NEXT: Body: 4181808080000B117; CHECK-NEXT: Body: 4181808080000B
121; CHECK-NEXT: - Type: DATA118; CHECK-NEXT: - Type: DATA
122; CHECK-NEXT: Segments:119; CHECK-NEXT: Segments:
...@@ -125,7 +122,7 @@ entry:...@@ -125,7 +122,7 @@ entry:
125; CHECK-NEXT: Offset:122; CHECK-NEXT: Offset:
126; CHECK-NEXT: Opcode: I32_CONST123; CHECK-NEXT: Opcode: I32_CONST
127; CHECK-NEXT: Value: 1024124; CHECK-NEXT: Value: 1024
128; CHECK-NEXT: Content: '0100000002000000'125; CHECK-NEXT: Content: '01000000'
129; CHECK-NEXT: - Type: CUSTOM126; CHECK-NEXT: - Type: CUSTOM
130; CHECK-NEXT: Name: name127; CHECK-NEXT: Name: name
131; CHECK-NEXT: FunctionNames:128; CHECK-NEXT: FunctionNames:
...@@ -138,7 +135,5 @@ entry:...@@ -138,7 +135,5 @@ entry:
138; CHECK-NEXT: - Index: 3135; CHECK-NEXT: - Index: 3
139; CHECK-NEXT: Name: exportWeak1136; CHECK-NEXT: Name: exportWeak1
140; CHECK-NEXT: - Index: 4137; CHECK-NEXT: - Index: 4
141; CHECK-NEXT: Name: weakFn
142; CHECK-NEXT: - Index: 5
143; CHECK-NEXT: Name: exportWeak2138; CHECK-NEXT: Name: exportWeak2
144; CHECK-NEXT: ...139; CHECK-NEXT: ...
deps/lld/test/wasm/weak-undefined.ll+4-9
...@@ -22,7 +22,8 @@ define i32* @get_address_of_global_var() #0 {...@@ -22,7 +22,8 @@ define i32* @get_address_of_global_var() #0 {
2222
23define void @_start() #0 {23define void @_start() #0 {
24entry:24entry:
25 %call = call i32* @get_address_of_global_var()25 %call1 = call i32* @get_address_of_global_var()
26 %call2 = call i8* @get_address_of_foo()
26 ret void27 ret void
27}28}
2829
...@@ -42,7 +43,7 @@ entry:...@@ -42,7 +43,7 @@ entry:
42; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ]43; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ]
43; CHECK-NEXT: - Type: TABLE44; CHECK-NEXT: - Type: TABLE
44; CHECK-NEXT: Tables:45; CHECK-NEXT: Tables:
45; CHECK-NEXT: - ElemType: ANYFUNC46; CHECK-NEXT: - ElemType: FUNCREF
46; CHECK-NEXT: Limits:47; CHECK-NEXT: Limits:
47; CHECK-NEXT: Flags: [ HAS_MAX ]48; CHECK-NEXT: Flags: [ HAS_MAX ]
48; CHECK-NEXT: Initial: 0x0000000149; CHECK-NEXT: Initial: 0x00000001
...@@ -84,12 +85,6 @@ entry:...@@ -84,12 +85,6 @@ entry:
84; CHECK-NEXT: - Name: _start85; CHECK-NEXT: - Name: _start
85; CHECK-NEXT: Kind: FUNCTION86; CHECK-NEXT: Kind: FUNCTION
86; CHECK-NEXT: Index: 387; CHECK-NEXT: Index: 3
87; CHECK-NEXT: - Name: get_address_of_foo
88; CHECK-NEXT: Kind: FUNCTION
89; CHECK-NEXT: Index: 1
90; CHECK-NEXT: - Name: get_address_of_global_var
91; CHECK-NEXT: Kind: FUNCTION
92; CHECK-NEXT: Index: 2
93; CHECK-NEXT: - Type: CODE88; CHECK-NEXT: - Type: CODE
94; CHECK-NEXT: Functions:89; CHECK-NEXT: Functions:
95; CHECK-NEXT: - Index: 090; CHECK-NEXT: - Index: 0
...@@ -103,5 +98,5 @@ entry:...@@ -103,5 +98,5 @@ entry:
103; CHECK-NEXT: Body: 4180808080000B98; CHECK-NEXT: Body: 4180808080000B
104; CHECK-NEXT: - Index: 399; CHECK-NEXT: - Index: 3
105; CHECK-NEXT: Locals:100; CHECK-NEXT: Locals:
106; CHECK-NEXT: Body: 1082808080001A0B101; CHECK-NEXT: Body: 1082808080001A1081808080001A0B
107; CHECK-NEXT: ...102; CHECK-NEXT: ...
deps/lld/tools/lld/lld.cpp+1-1
...@@ -138,7 +138,7 @@ int main(int Argc, const char **Argv) {...@@ -138,7 +138,7 @@ int main(int Argc, const char **Argv) {
138 return !wasm::link(Args, canExitEarly());138 return !wasm::link(Args, canExitEarly());
139 default:139 default:
140 die("lld is a generic driver.\n"140 die("lld is a generic driver.\n"
141 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-lld"141 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
142 " (WebAssembly) instead");142 " (WebAssembly) instead");
143 }143 }
144}144}
deps/lld/wasm/Config.h+8-1
...@@ -20,18 +20,22 @@ namespace wasm {...@@ -20,18 +20,22 @@ namespace wasm {
2020
21struct Configuration {21struct Configuration {
22 bool AllowUndefined;22 bool AllowUndefined;
23 bool CompressRelocTargets;23 bool CompressRelocations;
24 bool Demangle;24 bool Demangle;
25 bool DisableVerify;25 bool DisableVerify;
26 bool ExportAll;26 bool ExportAll;
27 bool ExportDynamic;
27 bool ExportTable;28 bool ExportTable;
28 bool GcSections;29 bool GcSections;
29 bool ImportMemory;30 bool ImportMemory;
31 bool SharedMemory;
30 bool ImportTable;32 bool ImportTable;
31 bool MergeDataSegments;33 bool MergeDataSegments;
34 bool Pie;
32 bool PrintGcSections;35 bool PrintGcSections;
33 bool Relocatable;36 bool Relocatable;
34 bool SaveTemps;37 bool SaveTemps;
38 bool Shared;
35 bool StripAll;39 bool StripAll;
36 bool StripDebug;40 bool StripDebug;
37 bool StackFirst;41 bool StackFirst;
...@@ -50,6 +54,9 @@ struct Configuration {...@@ -50,6 +54,9 @@ struct Configuration {
50 llvm::StringSet<> AllowUndefinedSymbols;54 llvm::StringSet<> AllowUndefinedSymbols;
51 std::vector<llvm::StringRef> SearchPaths;55 std::vector<llvm::StringRef> SearchPaths;
52 llvm::CachePruningPolicy ThinLTOCachePolicy;56 llvm::CachePruningPolicy ThinLTOCachePolicy;
57
58 // True if we are creating position-independent code.
59 bool Pic;
53};60};
5461
55// The only instance of Configuration struct.62// The only instance of Configuration struct.
deps/lld/wasm/Driver.cpp+184-104
...@@ -31,6 +31,7 @@...@@ -31,6 +31,7 @@
31#define DEBUG_TYPE "lld"31#define DEBUG_TYPE "lld"
3232
33using namespace llvm;33using namespace llvm;
34using namespace llvm::object;
34using namespace llvm::sys;35using namespace llvm::sys;
35using namespace llvm::wasm;36using namespace llvm::wasm;
3637
...@@ -78,7 +79,7 @@ private:...@@ -78,7 +79,7 @@ private:
7879
79bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,80bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
80 raw_ostream &Error) {81 raw_ostream &Error) {
81 errorHandler().LogName = sys::path::filename(Args[0]);82 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
82 errorHandler().ErrorOS = &Error;83 errorHandler().ErrorOS = &Error;
83 errorHandler().ColorDiagnostics = Error.has_colors();84 errorHandler().ColorDiagnostics = Error.has_colors();
84 errorHandler().ErrorLimitExceededMsg =85 errorHandler().ErrorLimitExceededMsg =
...@@ -186,8 +187,7 @@ static void readImportFile(StringRef Filename) {...@@ -186,8 +187,7 @@ static void readImportFile(StringRef Filename) {
186187
187// Returns slices of MB by parsing MB as an archive file.188// Returns slices of MB by parsing MB as an archive file.
188// Each slice consists of a member file in the archive.189// Each slice consists of a member file in the archive.
189std::vector<MemoryBufferRef> static getArchiveMembers(190std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) {
190 MemoryBufferRef MB) {
191 std::unique_ptr<Archive> File =191 std::unique_ptr<Archive> File =
192 CHECK(Archive::create(MB),192 CHECK(Archive::create(MB),
193 MB.getBufferIdentifier() + ": failed to parse archive");193 MB.getBufferIdentifier() + ": failed to parse archive");
...@@ -205,8 +205,8 @@ std::vector<MemoryBufferRef> static getArchiveMembers(...@@ -205,8 +205,8 @@ std::vector<MemoryBufferRef> static getArchiveMembers(
205 V.push_back(MBRef);205 V.push_back(MBRef);
206 }206 }
207 if (Err)207 if (Err)
208 fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +208 fatal(MB.getBufferIdentifier() +
209 toString(std::move(Err)));209 ": Archive::children failed: " + toString(std::move(Err)));
210210
211 // Take ownership of memory buffers created for members of thin archives.211 // Take ownership of memory buffers created for members of thin archives.
212 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())212 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
...@@ -306,17 +306,14 @@ static void handleWeakUndefines() {...@@ -306,17 +306,14 @@ static void handleWeakUndefines() {
306306
307 // It is possible for undefined functions not to have a signature (eg. if307 // It is possible for undefined functions not to have a signature (eg. if
308 // added via "--undefined"), but weak undefined ones do have a signature.308 // added via "--undefined"), but weak undefined ones do have a signature.
309 assert(FuncSym->FunctionType);309 assert(FuncSym->Signature);
310 const WasmSignature &Sig = *FuncSym->FunctionType;310 const WasmSignature &Sig = *FuncSym->Signature;
311311
312 // Add a synthetic dummy for weak undefined functions. These dummies will312 // Add a synthetic dummy for weak undefined functions. These dummies will
313 // be GC'd if not used as the target of any "call" instructions.313 // be GC'd if not used as the target of any "call" instructions.
314 Optional<std::string> SymName = demangleItanium(Sym->getName());314 std::string SymName = toString(*Sym);
315 StringRef DebugName =315 StringRef DebugName = Saver.save("undefined function " + SymName);
316 Saver.save("undefined function " +316 auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
317 (SymName ? StringRef(*SymName) : Sym->getName()));
318 SyntheticFunction *Func =
319 make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
320 Func->setBody(UnreachableFn);317 Func->setBody(UnreachableFn);
321 // Ensure it compares equal to the null pointer, and so that table relocs318 // Ensure it compares equal to the null pointer, and so that table relocs
322 // don't pull in the stub body (only call-operand relocs should do that).319 // don't pull in the stub body (only call-operand relocs should do that).
...@@ -328,51 +325,24 @@ static void handleWeakUndefines() {...@@ -328,51 +325,24 @@ static void handleWeakUndefines() {
328 }325 }
329}326}
330327
331// Force Sym to be entered in the output. Used for -u or equivalent.328// Some Config members do not directly correspond to any particular
332static Symbol *addUndefined(StringRef Name) {329// command line options, but computed based on other Config values.
333 Symbol *S = Symtab->addUndefinedFunction(Name, 0, nullptr, nullptr);330// This function initialize such members. See Config.h for the details
334331// of these values.
335 // Since symbol S may not be used inside the program, LTO may332static void setConfigs(opt::InputArgList &Args) {
336 // eliminate it. Mark the symbol as "used" to prevent it.
337 S->IsUsedInRegularObj = true;
338
339 return S;
340}
341
342void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
343 WasmOptTable Parser;
344 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
345
346 // Handle --help
347 if (Args.hasArg(OPT_help)) {
348 Parser.PrintHelp(outs(), ArgsArr[0], "LLVM Linker", false);
349 return;
350 }
351
352 // Handle --version
353 if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
354 outs() << getLLDVersion() << "\n";
355 return;
356 }
357
358 // Parse and evaluate -mllvm options.
359 std::vector<const char *> V;
360 V.push_back("wasm-ld (LLVM option parsing)");
361 for (auto *Arg : Args.filtered(OPT_mllvm))
362 V.push_back(Arg->getValue());
363 cl::ParseCommandLineOptions(V.size(), V.data());
364
365 errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
366
367 Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);333 Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
334 Config->CompressRelocations = Args.hasArg(OPT_compress_relocations);
368 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);335 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
369 Config->DisableVerify = Args.hasArg(OPT_disable_verify);336 Config->DisableVerify = Args.hasArg(OPT_disable_verify);
370 Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");337 Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
371 Config->ExportAll = Args.hasArg(OPT_export_all);338 Config->ExportAll = Args.hasArg(OPT_export_all);
339 Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic,
340 OPT_no_export_dynamic, false);
372 Config->ExportTable = Args.hasArg(OPT_export_table);341 Config->ExportTable = Args.hasArg(OPT_export_table);
373 errorHandler().FatalWarnings =342 errorHandler().FatalWarnings =
374 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);343 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
375 Config->ImportMemory = Args.hasArg(OPT_import_memory);344 Config->ImportMemory = Args.hasArg(OPT_import_memory);
345 Config->SharedMemory = Args.hasArg(OPT_shared_memory);
376 Config->ImportTable = Args.hasArg(OPT_import_table);346 Config->ImportTable = Args.hasArg(OPT_import_table);
377 Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);347 Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
378 Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);348 Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
...@@ -384,10 +354,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -384,10 +354,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
384 Config->MergeDataSegments =354 Config->MergeDataSegments =
385 Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,355 Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
386 !Config->Relocatable);356 !Config->Relocatable);
357 Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
387 Config->PrintGcSections =358 Config->PrintGcSections =
388 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);359 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
389 Config->SaveTemps = Args.hasArg(OPT_save_temps);360 Config->SaveTemps = Args.hasArg(OPT_save_temps);
390 Config->SearchPaths = args::getStrings(Args, OPT_L);361 Config->SearchPaths = args::getStrings(Args, OPT_L);
362 Config->Shared = Args.hasArg(OPT_shared);
391 Config->StripAll = Args.hasArg(OPT_strip_all);363 Config->StripAll = Args.hasArg(OPT_strip_all);
392 Config->StripDebug = Args.hasArg(OPT_strip_debug);364 Config->StripDebug = Args.hasArg(OPT_strip_debug);
393 Config->StackFirst = Args.hasArg(OPT_stack_first);365 Config->StackFirst = Args.hasArg(OPT_stack_first);
...@@ -404,8 +376,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -404,8 +376,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
404 Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);376 Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
405 Config->ZStackSize =377 Config->ZStackSize =
406 args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);378 args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
379}
407380
408 Config->CompressRelocTargets = Config->Optimize > 0 && !Config->Relocatable;381// Some command line options or some combinations of them are not allowed.
382// This function checks for such errors.
383static void checkOptions(opt::InputArgList &Args) {
384 if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations)
385 error("--compress-relocations is incompatible with output debug"
386 " information. Please pass --strip-debug or --strip-all");
409387
410 if (Config->LTOO > 3)388 if (Config->LTOO > 3)
411 error("invalid optimization level for LTO: " + Twine(Config->LTOO));389 error("invalid optimization level for LTO: " + Twine(Config->LTOO));
...@@ -414,13 +392,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -414,13 +392,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
414 if (Config->ThinLTOJobs == 0)392 if (Config->ThinLTOJobs == 0)
415 error("--thinlto-jobs: number of threads must be > 0");393 error("--thinlto-jobs: number of threads must be > 0");
416394
417 if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))395 if (Config->Pie && Config->Shared)
418 readImportFile(Arg->getValue());396 error("-shared and -pie may not be used together");
419
420 if (!Args.hasArg(OPT_INPUT)) {
421 error("no input files");
422 return;
423 }
424397
425 if (Config->OutputFile.empty())398 if (Config->OutputFile.empty())
426 error("no output file specified");399 error("no output file specified");
...@@ -433,46 +406,151 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -433,46 +406,151 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
433 error("entry point specified for relocatable output file");406 error("entry point specified for relocatable output file");
434 if (Config->GcSections)407 if (Config->GcSections)
435 error("-r and --gc-sections may not be used together");408 error("-r and --gc-sections may not be used together");
409 if (Config->CompressRelocations)
410 error("-r -and --compress-relocations may not be used together");
436 if (Args.hasArg(OPT_undefined))411 if (Args.hasArg(OPT_undefined))
437 error("-r -and --undefined may not be used together");412 error("-r -and --undefined may not be used together");
413 if (Config->Pie)
414 error("-r and -pie may not be used together");
438 }415 }
416}
439417
440 Symbol *EntrySym = nullptr;418// Force Sym to be entered in the output. Used for -u or equivalent.
441 if (!Config->Relocatable) {419static Symbol *handleUndefined(StringRef Name) {
420 Symbol *Sym = Symtab->find(Name);
421 if (!Sym)
422 return nullptr;
423
424 // Since symbol S may not be used inside the program, LTO may
425 // eliminate it. Mark the symbol as "used" to prevent it.
426 Sym->IsUsedInRegularObj = true;
427
428 if (auto *LazySym = dyn_cast<LazySymbol>(Sym))
429 LazySym->fetch();
430
431 return Sym;
432}
433
434static UndefinedGlobal *
435createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) {
436 auto *Sym =
437 cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type));
438 Config->AllowUndefinedSymbols.insert(Sym->getName());
439 Sym->IsUsedInRegularObj = true;
440 return Sym;
441}
442
443// Create ABI-defined synthetic symbols
444static void createSyntheticSymbols() {
445 static WasmSignature NullSignature = {{}, {}};
446 static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false};
447 static llvm::wasm::WasmGlobalType MutableGlobalTypeI32 = {WASM_TYPE_I32,
448 true};
449
450 if (!Config->Relocatable)
451 WasmSym::CallCtors = Symtab->addSyntheticFunction(
452 "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
453 make<SyntheticFunction>(NullSignature, "__wasm_call_ctors"));
454
455 // The __stack_pointer is imported in the shared library case, and exported
456 // in the non-shared (executable) case.
457 if (Config->Shared) {
458 WasmSym::StackPointer =
459 createUndefinedGlobal("__stack_pointer", &MutableGlobalTypeI32);
460 } else {
442 llvm::wasm::WasmGlobal Global;461 llvm::wasm::WasmGlobal Global;
443 Global.Type = {WASM_TYPE_I32, true};462 Global.Type = {WASM_TYPE_I32, true};
444 Global.InitExpr.Value.Int32 = 0;463 Global.InitExpr.Value.Int32 = 0;
445 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;464 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
446 Global.SymbolName = "__stack_pointer";465 Global.SymbolName = "__stack_pointer";
447 InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr);466 auto *StackPointer = make<InputGlobal>(Global, nullptr);
448 StackPointer->Live = true;467 StackPointer->Live = true;
449468 // For non-PIC code
450 static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
451
452 // Add synthetic symbols before any others
453 WasmSym::CallCtors = Symtab->addSyntheticFunction(
454 "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
455 make<SyntheticFunction>(NullSignature, "__wasm_call_ctors"));
456 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global469 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
457 // spec proposal is implemented in all major browsers.470 // spec proposal is implemented in all major browsers.
458 // See: https://github.com/WebAssembly/mutable-global471 // See: https://github.com/WebAssembly/mutable-global
459 WasmSym::StackPointer = Symtab->addSyntheticGlobal(472 WasmSym::StackPointer = Symtab->addSyntheticGlobal(
460 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);473 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
461 WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);474 WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);
462 WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
463 "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
464 WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);475 WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
465476
466 // For now, since we don't actually use the start function as the477 // These two synthetic symbols exist purely for the embedder so we always
467 // wasm start symbol, we don't need to care about it signature.478 // want to export them.
468 if (!Config->Entry.empty())479 WasmSym::HeapBase->ForceExport = true;
469 EntrySym = addUndefined(Config->Entry);480 WasmSym::DataEnd->ForceExport = true;
481 }
482
483 if (Config->Pic) {
484 // For PIC code, we import two global variables (__memory_base and
485 // __table_base) from the environment and use these as the offset at
486 // which to load our static data and function table.
487 // See:
488 // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
489 WasmSym::MemoryBase =
490 createUndefinedGlobal("__memory_base", &GlobalTypeI32);
491 WasmSym::TableBase = createUndefinedGlobal("__table_base", &GlobalTypeI32);
492 WasmSym::MemoryBase->markLive();
493 WasmSym::TableBase->markLive();
494 }
495
496 WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
497 "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
498}
499
500void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
501 WasmOptTable Parser;
502 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
503
504 // Handle --help
505 if (Args.hasArg(OPT_help)) {
506 Parser.PrintHelp(outs(),
507 (std::string(ArgsArr[0]) + " [options] file...").c_str(),
508 "LLVM Linker", false);
509 return;
510 }
470511
471 // Handle the `--undefined <sym>` options.512 // Handle --version
472 for (auto *Arg : Args.filtered(OPT_undefined))513 if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
473 addUndefined(Arg->getValue());514 outs() << getLLDVersion() << "\n";
515 return;
474 }516 }
475517
518 // Parse and evaluate -mllvm options.
519 std::vector<const char *> V;
520 V.push_back("wasm-ld (LLVM option parsing)");
521 for (auto *Arg : Args.filtered(OPT_mllvm))
522 V.push_back(Arg->getValue());
523 cl::ParseCommandLineOptions(V.size(), V.data());
524
525 errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
526
527 setConfigs(Args);
528 checkOptions(Args);
529
530 if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
531 readImportFile(Arg->getValue());
532
533 if (!Args.hasArg(OPT_INPUT)) {
534 error("no input files");
535 return;
536 }
537
538 Config->Pic = Config->Pie || Config->Shared;
539
540 if (Config->Pic) {
541 if (Config->ExportTable)
542 error("-shared/-pie is incompatible with --export-table");
543 Config->ImportTable = true;
544 }
545
546 if (Config->Shared) {
547 Config->ExportDynamic = true;
548 Config->AllowUndefined = true;
549 }
550
551 if (!Config->Relocatable)
552 createSyntheticSymbols();
553
476 createFiles(Args);554 createFiles(Args);
477 if (errorCount())555 if (errorCount())
478 return;556 return;
...@@ -484,44 +562,46 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {...@@ -484,44 +562,46 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
484 if (errorCount())562 if (errorCount())
485 return;563 return;
486564
487 // Add synthetic dummies for weak undefined functions.565 // Handle the `--undefined <sym>` options.
488 if (!Config->Relocatable)566 for (auto *Arg : Args.filtered(OPT_undefined))
489 handleWeakUndefines();567 handleUndefined(Arg->getValue());
490568
491 // Handle --export.569 // Handle the `--export <sym>` options
570 // This works like --undefined but also exports the symbol if its found
492 for (auto *Arg : Args.filtered(OPT_export)) {571 for (auto *Arg : Args.filtered(OPT_export)) {
493 StringRef Name = Arg->getValue();572 Symbol *Sym = handleUndefined(Arg->getValue());
494 Symbol *Sym = Symtab->find(Name);
495 if (Sym && Sym->isDefined())573 if (Sym && Sym->isDefined())
496 Sym->ForceExport = true;574 Sym->ForceExport = true;
497 else if (!Config->AllowUndefined)575 else if (!Config->AllowUndefined)
498 error("symbol exported via --export not found: " + Name);576 error(Twine("symbol exported via --export not found: ") +
577 Arg->getValue());
499 }578 }
500579
501 // Do link-time optimization if given files are LLVM bitcode files.580 Symbol *EntrySym = nullptr;
502 // This compiles bitcode files into real object files.581 if (!Config->Relocatable) {
503 Symtab->addCombinedLTOObject();582 // Add synthetic dummies for weak undefined functions.
504 if (errorCount())583 handleWeakUndefines();
505 return;
506584
507 // Make sure we have resolved all symbols.585 if (!Config->Shared && !Config->Entry.empty()) {
508 if (!Config->Relocatable && !Config->AllowUndefined) {586 EntrySym = handleUndefined(Config->Entry);
509 Symtab->reportRemainingUndefines();587 if (EntrySym && EntrySym->isDefined())
510 } else {588 EntrySym->ForceExport = true;
511 // Even when using --allow-undefined we still want to report the absence of589 else
512 // our initial set of undefined symbols (i.e. the entry point and symbols590 error("entry symbol not defined (pass --no-entry to supress): " +
513 // specified via --undefined).591 Config->Entry);
514 // Part of the reason for this is that these function don't have signatures
515 // so which means they cannot be written as wasm function imports.
516 for (auto *Arg : Args.filtered(OPT_undefined)) {
517 Symbol *Sym = Symtab->find(Arg->getValue());
518 if (!Sym->isDefined())
519 error("symbol forced with --undefined not found: " + Sym->getName());
520 }592 }
521 if (EntrySym && !EntrySym->isDefined())593
522 error("entry symbol not defined (pass --no-entry to supress): " +594 // Make sure we have resolved all symbols.
523 EntrySym->getName());595 if (!Config->AllowUndefined)
596 Symtab->reportRemainingUndefines();
524 }597 }
598
599 if (errorCount())
600 return;
601
602 // Do link-time optimization if given files are LLVM bitcode files.
603 // This compiles bitcode files into real object files.
604 Symtab->addCombinedLTOObject();
525 if (errorCount())605 if (errorCount())
526 return;606 return;
527607
deps/lld/wasm/InputChunks.cpp+12-15
...@@ -25,7 +25,9 @@ using namespace lld::wasm;...@@ -25,7 +25,9 @@ using namespace lld::wasm;
2525
26static StringRef ReloctTypeToString(uint8_t RelocType) {26static StringRef ReloctTypeToString(uint8_t RelocType) {
27 switch (RelocType) {27 switch (RelocType) {
28#define WASM_RELOC(NAME, REL) case REL: return #NAME;28#define WASM_RELOC(NAME, REL) \
29 case REL: \
30 return #NAME;
29#include "llvm/BinaryFormat/WasmRelocs.def"31#include "llvm/BinaryFormat/WasmRelocs.def"
30#undef WASM_RELOC32#undef WASM_RELOC
31 }33 }
...@@ -43,16 +45,6 @@ StringRef InputChunk::getComdatName() const {...@@ -43,16 +45,6 @@ StringRef InputChunk::getComdatName() const {
43 return File->getWasmObj()->linkingData().Comdats[Index];45 return File->getWasmObj()->linkingData().Comdats[Index];
44}46}
4547
46void InputChunk::copyRelocations(const WasmSection &Section) {
47 if (Section.Relocations.empty())
48 return;
49 size_t Start = getInputSectionOffset();
50 size_t Size = getInputSize();
51 for (const WasmRelocation &R : Section.Relocations)
52 if (R.Offset >= Start && R.Offset < Start + Size)
53 Relocations.push_back(R);
54}
55
56void InputChunk::verifyRelocTargets() const {48void InputChunk::verifyRelocTargets() const {
57 for (const WasmRelocation &Rel : Relocations) {49 for (const WasmRelocation &Rel : Relocations) {
58 uint32_t ExistingValue;50 uint32_t ExistingValue;
...@@ -63,6 +55,7 @@ void InputChunk::verifyRelocTargets() const {...@@ -63,6 +55,7 @@ void InputChunk::verifyRelocTargets() const {
63 case R_WEBASSEMBLY_TYPE_INDEX_LEB:55 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
64 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:56 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
65 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:57 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
58 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
66 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:59 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
67 ExistingValue = decodeULEB128(Loc, &BytesRead);60 ExistingValue = decodeULEB128(Loc, &BytesRead);
68 break;61 break;
...@@ -119,6 +112,7 @@ void InputChunk::writeTo(uint8_t *Buf) const {...@@ -119,6 +112,7 @@ void InputChunk::writeTo(uint8_t *Buf) const {
119 case R_WEBASSEMBLY_TYPE_INDEX_LEB:112 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
120 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:113 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
121 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:114 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
115 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
122 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:116 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
123 encodeULEB128(Value, Loc, 5);117 encodeULEB128(Value, Loc, 5);
124 break;118 break;
...@@ -188,6 +182,7 @@ static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,...@@ -188,6 +182,7 @@ static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
188 case R_WEBASSEMBLY_TYPE_INDEX_LEB:182 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
189 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:183 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
190 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:184 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
185 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
191 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:186 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
192 return encodeULEB128(Value, Buf);187 return encodeULEB128(Value, Buf);
193 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:188 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
...@@ -203,6 +198,7 @@ static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {...@@ -203,6 +198,7 @@ static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {
203 case R_WEBASSEMBLY_TYPE_INDEX_LEB:198 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
204 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:199 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
205 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:200 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
201 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
206 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:202 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
207 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:203 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
208 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:204 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
...@@ -228,7 +224,7 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {...@@ -228,7 +224,7 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {
228// This function only computes the final output size. It must be called224// This function only computes the final output size. It must be called
229// before getSize() is used to calculate of layout of the code section.225// before getSize() is used to calculate of layout of the code section.
230void InputFunction::calculateSize() {226void InputFunction::calculateSize() {
231 if (!File || !Config->CompressRelocTargets)227 if (!File || !Config->CompressRelocations)
232 return;228 return;
233229
234 LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");230 LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");
...@@ -242,7 +238,7 @@ void InputFunction::calculateSize() {...@@ -242,7 +238,7 @@ void InputFunction::calculateSize() {
242 uint32_t End = Start + Function->Size;238 uint32_t End = Start + Function->Size;
243239
244 uint32_t LastRelocEnd = Start + FunctionSizeLength;240 uint32_t LastRelocEnd = Start + FunctionSizeLength;
245 for (WasmRelocation &Rel : Relocations) {241 for (const WasmRelocation &Rel : Relocations) {
246 LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n");242 LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n");
247 CompressedFuncSize += Rel.Offset - LastRelocEnd;243 CompressedFuncSize += Rel.Offset - LastRelocEnd;
248 CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));244 CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));
...@@ -263,11 +259,12 @@ void InputFunction::calculateSize() {...@@ -263,11 +259,12 @@ void InputFunction::calculateSize() {
263// Override the default writeTo method so that we can (optionally) write the259// Override the default writeTo method so that we can (optionally) write the
264// compressed version of the function.260// compressed version of the function.
265void InputFunction::writeTo(uint8_t *Buf) const {261void InputFunction::writeTo(uint8_t *Buf) const {
266 if (!File || !Config->CompressRelocTargets)262 if (!File || !Config->CompressRelocations)
267 return InputChunk::writeTo(Buf);263 return InputChunk::writeTo(Buf);
268264
269 Buf += OutputOffset;265 Buf += OutputOffset;
270 uint8_t *Orig = Buf; (void)Orig;266 uint8_t *Orig = Buf;
267 (void)Orig;
271268
272 const uint8_t *SecStart = File->CodeSection->Content.data();269 const uint8_t *SecStart = File->CodeSection->Content.data();
273 const uint8_t *FuncStart = SecStart + getInputSectionOffset();270 const uint8_t *FuncStart = SecStart + getInputSectionOffset();
deps/lld/wasm/InputChunks.h+14-26
...@@ -24,18 +24,9 @@...@@ -24,18 +24,9 @@
24#include "Config.h"24#include "Config.h"
25#include "InputFiles.h"25#include "InputFiles.h"
26#include "lld/Common/ErrorHandler.h"26#include "lld/Common/ErrorHandler.h"
27#include "lld/Common/LLVM.h"
27#include "llvm/Object/Wasm.h"28#include "llvm/Object/Wasm.h"
2829
29using llvm::object::WasmSection;
30using llvm::object::WasmSegment;
31using llvm::wasm::WasmFunction;
32using llvm::wasm::WasmRelocation;
33using llvm::wasm::WasmSignature;
34
35namespace llvm {
36class raw_ostream;
37}
38
39namespace lld {30namespace lld {
40namespace wasm {31namespace wasm {
4132
...@@ -49,17 +40,18 @@ public:...@@ -49,17 +40,18 @@ public:
49 Kind kind() const { return SectionKind; }40 Kind kind() const { return SectionKind; }
5041
51 virtual uint32_t getSize() const { return data().size(); }42 virtual uint32_t getSize() const { return data().size(); }
5243 virtual uint32_t getInputSize() const { return getSize(); };
53 void copyRelocations(const WasmSection &Section);
5444
55 virtual void writeTo(uint8_t *SectionStart) const;45 virtual void writeTo(uint8_t *SectionStart) const;
5646
57 ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }47 ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
48 void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; }
5849
59 virtual StringRef getName() const = 0;50 virtual StringRef getName() const = 0;
60 virtual StringRef getDebugName() const = 0;51 virtual StringRef getDebugName() const = 0;
61 virtual uint32_t getComdat() const = 0;52 virtual uint32_t getComdat() const = 0;
62 StringRef getComdatName() const;53 StringRef getComdatName() const;
54 virtual uint32_t getInputSectionOffset() const = 0;
6355
64 size_t NumRelocations() const { return Relocations.size(); }56 size_t NumRelocations() const { return Relocations.size(); }
65 void writeRelocations(llvm::raw_ostream &OS) const;57 void writeRelocations(llvm::raw_ostream &OS) const;
...@@ -77,14 +69,12 @@ protected:...@@ -77,14 +69,12 @@ protected:
77 : File(F), Live(!Config->GcSections), SectionKind(K) {}69 : File(F), Live(!Config->GcSections), SectionKind(K) {}
78 virtual ~InputChunk() = default;70 virtual ~InputChunk() = default;
79 virtual ArrayRef<uint8_t> data() const = 0;71 virtual ArrayRef<uint8_t> data() const = 0;
80 virtual uint32_t getInputSectionOffset() const = 0;
81 virtual uint32_t getInputSize() const { return getSize(); };
8272
83 // Verifies the existing data at relocation targets matches our expectations.73 // Verifies the existing data at relocation targets matches our expectations.
84 // This is performed only debug builds as an extra sanity check.74 // This is performed only debug builds as an extra sanity check.
85 void verifyRelocTargets() const;75 void verifyRelocTargets() const;
8676
87 std::vector<WasmRelocation> Relocations;77 ArrayRef<WasmRelocation> Relocations;
88 Kind SectionKind;78 Kind SectionKind;
89};79};
9080
...@@ -107,15 +97,15 @@ public:...@@ -107,15 +97,15 @@ public:
107 StringRef getName() const override { return Segment.Data.Name; }97 StringRef getName() const override { return Segment.Data.Name; }
108 StringRef getDebugName() const override { return StringRef(); }98 StringRef getDebugName() const override { return StringRef(); }
109 uint32_t getComdat() const override { return Segment.Data.Comdat; }99 uint32_t getComdat() const override { return Segment.Data.Comdat; }
100 uint32_t getInputSectionOffset() const override {
101 return Segment.SectionOffset;
102 }
110103
111 const OutputSegment *OutputSeg = nullptr;104 const OutputSegment *OutputSeg = nullptr;
112 int32_t OutputSegmentOffset = 0;105 int32_t OutputSegmentOffset = 0;
113106
114protected:107protected:
115 ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }108 ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }
116 uint32_t getInputSectionOffset() const override {
117 return Segment.SectionOffset;
118 }
119109
120 const WasmSegment &Segment;110 const WasmSegment &Segment;
121};111};
...@@ -139,15 +129,19 @@ public:...@@ -139,15 +129,19 @@ public:
139 uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }129 uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
140 uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }130 uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
141 uint32_t getSize() const override {131 uint32_t getSize() const override {
142 if (Config->CompressRelocTargets && File) {132 if (Config->CompressRelocations && File) {
143 assert(CompressedSize);133 assert(CompressedSize);
144 return CompressedSize;134 return CompressedSize;
145 }135 }
146 return data().size();136 return data().size();
147 }137 }
138 uint32_t getInputSize() const override { return Function->Size; }
148 uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }139 uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
149 bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }140 bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
150 void setFunctionIndex(uint32_t Index);141 void setFunctionIndex(uint32_t Index);
142 uint32_t getInputSectionOffset() const override {
143 return Function->CodeSectionOffset;
144 }
151 uint32_t getTableIndex() const { return TableIndex.getValue(); }145 uint32_t getTableIndex() const { return TableIndex.getValue(); }
152 bool hasTableIndex() const { return TableIndex.hasValue(); }146 bool hasTableIndex() const { return TableIndex.hasValue(); }
153 void setTableIndex(uint32_t Index);147 void setTableIndex(uint32_t Index);
...@@ -162,17 +156,11 @@ public:...@@ -162,17 +156,11 @@ public:
162156
163protected:157protected:
164 ArrayRef<uint8_t> data() const override {158 ArrayRef<uint8_t> data() const override {
165 assert(!Config->CompressRelocTargets);159 assert(!Config->CompressRelocations);
166 return File->CodeSection->Content.slice(getInputSectionOffset(),160 return File->CodeSection->Content.slice(getInputSectionOffset(),
167 Function->Size);161 Function->Size);
168 }162 }
169163
170 uint32_t getInputSize() const override { return Function->Size; }
171
172 uint32_t getInputSectionOffset() const override {
173 return Function->CodeSectionOffset;
174 }
175
176 const WasmFunction *Function;164 const WasmFunction *Function;
177 llvm::Optional<uint32_t> FunctionIndex;165 llvm::Optional<uint32_t> FunctionIndex;
178 llvm::Optional<uint32_t> TableIndex;166 llvm::Optional<uint32_t> TableIndex;
deps/lld/wasm/InputEvent.h created+63
...@@ -0,0 +1,63 @@
1//===- InputEvent.h ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Wasm events are features that suspend the current execution and transfer the
11// control flow to a corresponding handler. Currently the only supported event
12// kind is exceptions.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLD_WASM_INPUT_EVENT_H
17#define LLD_WASM_INPUT_EVENT_H
18
19#include "Config.h"
20#include "InputFiles.h"
21#include "WriterUtils.h"
22#include "lld/Common/ErrorHandler.h"
23#include "llvm/Object/Wasm.h"
24
25namespace lld {
26namespace wasm {
27
28// Represents a single Wasm Event within an input file. These are combined to
29// form the final EVENTS section.
30class InputEvent {
31public:
32 InputEvent(const WasmSignature &S, const WasmEvent &E, ObjFile *F)
33 : File(F), Event(E), Signature(S), Live(!Config->GcSections) {}
34
35 StringRef getName() const { return Event.SymbolName; }
36 const WasmEventType &getType() const { return Event.Type; }
37
38 uint32_t getEventIndex() const { return EventIndex.getValue(); }
39 bool hasEventIndex() const { return EventIndex.hasValue(); }
40 void setEventIndex(uint32_t Index) {
41 assert(!hasEventIndex());
42 EventIndex = Index;
43 }
44
45 ObjFile *File;
46 WasmEvent Event;
47 const WasmSignature &Signature;
48
49 bool Live = false;
50
51protected:
52 llvm::Optional<uint32_t> EventIndex;
53};
54
55} // namespace wasm
56
57inline std::string toString(const wasm::InputEvent *E) {
58 return (toString(E->File) + ":(" + E->getName() + ")").str();
59}
60
61} // namespace lld
62
63#endif // LLD_WASM_INPUT_EVENT_H
deps/lld/wasm/InputFiles.cpp+71-22
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10#include "InputFiles.h"10#include "InputFiles.h"
11#include "Config.h"11#include "Config.h"
12#include "InputChunks.h"12#include "InputChunks.h"
13#include "InputEvent.h"
13#include "InputGlobal.h"14#include "InputGlobal.h"
14#include "SymbolTable.h"15#include "SymbolTable.h"
15#include "lld/Common/ErrorHandler.h"16#include "lld/Common/ErrorHandler.h"
...@@ -57,12 +58,13 @@ void ObjFile::dumpInfo() const {...@@ -57,12 +58,13 @@ void ObjFile::dumpInfo() const {
57 log("info for: " + getName() +58 log("info for: " + getName() +
58 "\n Symbols : " + Twine(Symbols.size()) +59 "\n Symbols : " + Twine(Symbols.size()) +
59 "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) +60 "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) +
60 "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()));61 "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()) +
62 "\n Event Imports : " + Twine(WasmObj->getNumImportedEvents()));
61}63}
6264
63// Relocations contain either symbol or type indices. This function takes a65// Relocations contain either symbol or type indices. This function takes a
64// relocation and returns relocated index (i.e. translates from the input66// relocation and returns relocated index (i.e. translates from the input
65// sybmol/type space to the output symbol/type space).67// symbol/type space to the output symbol/type space).
66uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {68uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
67 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {69 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
68 assert(TypeIsUsed[Reloc.Index]);70 assert(TypeIsUsed[Reloc.Index]);
...@@ -94,16 +96,17 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {...@@ -94,16 +96,17 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
94 switch (Reloc.Type) {96 switch (Reloc.Type) {
95 case R_WEBASSEMBLY_TABLE_INDEX_I32:97 case R_WEBASSEMBLY_TABLE_INDEX_I32:
96 case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {98 case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
97 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];99 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
98 return TableEntries[Sym.Info.ElementIndex];100 return TableEntries[Sym.Info.ElementIndex];
99 }101 }
100 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:102 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
101 case R_WEBASSEMBLY_MEMORY_ADDR_I32:103 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
102 case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {104 case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
103 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];105 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
104 if (Sym.isUndefined())106 if (Sym.isUndefined())
105 return 0;107 return 0;
106 const WasmSegment& Segment = WasmObj->dataSegments()[Sym.Info.DataRef.Segment];108 const WasmSegment &Segment =
109 WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
107 return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +110 return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
108 Reloc.Addend;111 Reloc.Addend;
109 }112 }
...@@ -118,8 +121,9 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {...@@ -118,8 +121,9 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
118 case R_WEBASSEMBLY_TYPE_INDEX_LEB:121 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
119 return Reloc.Index;122 return Reloc.Index;
120 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:123 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
121 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: {124 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
122 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];125 case R_WEBASSEMBLY_EVENT_INDEX_LEB: {
126 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
123 return Sym.Info.ElementIndex;127 return Sym.Info.ElementIndex;
124 }128 }
125 default:129 default:
...@@ -146,10 +150,13 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {...@@ -146,10 +150,13 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
146 return getFunctionSymbol(Reloc.Index)->getFunctionIndex();150 return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
147 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:151 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
148 return getGlobalSymbol(Reloc.Index)->getGlobalIndex();152 return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
153 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
154 return getEventSymbol(Reloc.Index)->getEventIndex();
149 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:155 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
150 if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {156 if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
151 return Sym->Function->OutputOffset +157 if (Sym->isLive())
152 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;158 return Sym->Function->OutputOffset +
159 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
153 }160 }
154 return 0;161 return 0;
155 case R_WEBASSEMBLY_SECTION_OFFSET_I32:162 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
...@@ -159,6 +166,37 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {...@@ -159,6 +166,37 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
159 }166 }
160}167}
161168
169template <class T>
170static void setRelocs(const std::vector<T *> &Chunks,
171 const WasmSection *Section) {
172 if (!Section)
173 return;
174
175 ArrayRef<WasmRelocation> Relocs = Section->Relocations;
176 assert(std::is_sorted(Relocs.begin(), Relocs.end(),
177 [](const WasmRelocation &R1, const WasmRelocation &R2) {
178 return R1.Offset < R2.Offset;
179 }));
180 assert(std::is_sorted(
181 Chunks.begin(), Chunks.end(), [](InputChunk *C1, InputChunk *C2) {
182 return C1->getInputSectionOffset() < C2->getInputSectionOffset();
183 }));
184
185 auto RelocsNext = Relocs.begin();
186 auto RelocsEnd = Relocs.end();
187 auto RelocLess = [](const WasmRelocation &R, uint32_t Val) {
188 return R.Offset < Val;
189 };
190 for (InputChunk *C : Chunks) {
191 auto RelocsStart = std::lower_bound(RelocsNext, RelocsEnd,
192 C->getInputSectionOffset(), RelocLess);
193 RelocsNext = std::lower_bound(
194 RelocsStart, RelocsEnd, C->getInputSectionOffset() + C->getInputSize(),
195 RelocLess);
196 C->setRelocations(ArrayRef<WasmRelocation>(RelocsStart, RelocsNext));
197 }
198}
199
162void ObjFile::parse() {200void ObjFile::parse() {
163 // Parse a memory buffer as a wasm file.201 // Parse a memory buffer as a wasm file.
164 LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");202 LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
...@@ -200,7 +238,7 @@ void ObjFile::parse() {...@@ -200,7 +238,7 @@ void ObjFile::parse() {
200 DataSection = &Section;238 DataSection = &Section;
201 } else if (Section.Type == WASM_SEC_CUSTOM) {239 } else if (Section.Type == WASM_SEC_CUSTOM) {
202 CustomSections.emplace_back(make<InputSection>(Section, this));240 CustomSections.emplace_back(make<InputSection>(Section, this));
203 CustomSections.back()->copyRelocations(Section);241 CustomSections.back()->setRelocations(Section.Relocations);
204 CustomSectionsByIndex[SectionIndex] = CustomSections.back();242 CustomSectionsByIndex[SectionIndex] = CustomSections.back();
205 }243 }
206 SectionIndex++;244 SectionIndex++;
...@@ -215,11 +253,9 @@ void ObjFile::parse() {...@@ -215,11 +253,9 @@ void ObjFile::parse() {
215 UsedComdats[I] = Symtab->addComdat(Comdats[I]);253 UsedComdats[I] = Symtab->addComdat(Comdats[I]);
216254
217 // Populate `Segments`.255 // Populate `Segments`.
218 for (const WasmSegment &S : WasmObj->dataSegments()) {256 for (const WasmSegment &S : WasmObj->dataSegments())
219 InputSegment *Seg = make<InputSegment>(S, this);257 Segments.emplace_back(make<InputSegment>(S, this));
220 Seg->copyRelocations(*DataSection);258 setRelocs(Segments, DataSection);
221 Segments.emplace_back(Seg);
222 }
223259
224 // Populate `Functions`.260 // Populate `Functions`.
225 ArrayRef<WasmFunction> Funcs = WasmObj->functions();261 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
...@@ -227,17 +263,19 @@ void ObjFile::parse() {...@@ -227,17 +263,19 @@ void ObjFile::parse() {
227 ArrayRef<WasmSignature> Types = WasmObj->types();263 ArrayRef<WasmSignature> Types = WasmObj->types();
228 Functions.reserve(Funcs.size());264 Functions.reserve(Funcs.size());
229265
230 for (size_t I = 0, E = Funcs.size(); I != E; ++I) {266 for (size_t I = 0, E = Funcs.size(); I != E; ++I)
231 InputFunction *F =267 Functions.emplace_back(
232 make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this);268 make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this));
233 F->copyRelocations(*CodeSection);269 setRelocs(Functions, CodeSection);
234 Functions.emplace_back(F);
235 }
236270
237 // Populate `Globals`.271 // Populate `Globals`.
238 for (const WasmGlobal &G : WasmObj->globals())272 for (const WasmGlobal &G : WasmObj->globals())
239 Globals.emplace_back(make<InputGlobal>(G, this));273 Globals.emplace_back(make<InputGlobal>(G, this));
240274
275 // Populate `Events`.
276 for (const WasmEvent &E : WasmObj->events())
277 Events.emplace_back(make<InputEvent>(Types[E.Type.SigIndex], E, this));
278
241 // Populate `Symbols` based on the WasmSymbols in the object.279 // Populate `Symbols` based on the WasmSymbols in the object.
242 Symbols.reserve(WasmObj->getNumberOfSymbols());280 Symbols.reserve(WasmObj->getNumberOfSymbols());
243 for (const SymbolRef &Sym : WasmObj->symbols()) {281 for (const SymbolRef &Sym : WasmObj->symbols()) {
...@@ -264,6 +302,10 @@ GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {...@@ -264,6 +302,10 @@ GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
264 return cast<GlobalSymbol>(Symbols[Index]);302 return cast<GlobalSymbol>(Symbols[Index]);
265}303}
266304
305EventSymbol *ObjFile::getEventSymbol(uint32_t Index) const {
306 return cast<EventSymbol>(Symbols[Index]);
307}
308
267SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const {309SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const {
268 return cast<SectionSymbol>(Symbols[Index]);310 return cast<SectionSymbol>(Symbols[Index]);
269}311}
...@@ -318,6 +360,13 @@ Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {...@@ -318,6 +360,13 @@ Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {
318 assert(Sym.isBindingLocal());360 assert(Sym.isBindingLocal());
319 return make<SectionSymbol>(Name, Flags, Section, this);361 return make<SectionSymbol>(Name, Flags, Section, this);
320 }362 }
363 case WASM_SYMBOL_TYPE_EVENT: {
364 InputEvent *Event =
365 Events[Sym.Info.ElementIndex - WasmObj->getNumImportedEvents()];
366 if (Sym.isBindingLocal())
367 return make<DefinedEvent>(Name, Flags, this, Event);
368 return Symtab->addDefinedEvent(Name, Flags, this, Event);
369 }
321 }370 }
322 llvm_unreachable("unknown symbol kind");371 llvm_unreachable("unknown symbol kind");
323}372}
...@@ -328,7 +377,7 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {...@@ -328,7 +377,7 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
328377
329 switch (Sym.Info.Kind) {378 switch (Sym.Info.Kind) {
330 case WASM_SYMBOL_TYPE_FUNCTION:379 case WASM_SYMBOL_TYPE_FUNCTION:
331 return Symtab->addUndefinedFunction(Name, Flags, this, Sym.FunctionType);380 return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature);
332 case WASM_SYMBOL_TYPE_DATA:381 case WASM_SYMBOL_TYPE_DATA:
333 return Symtab->addUndefinedData(Name, Flags, this);382 return Symtab->addUndefinedData(Name, Flags, this);
334 case WASM_SYMBOL_TYPE_GLOBAL:383 case WASM_SYMBOL_TYPE_GLOBAL:
deps/lld/wasm/InputFiles.h+5-17
...@@ -20,21 +20,6 @@...@@ -20,21 +20,6 @@
20#include "llvm/Support/MemoryBuffer.h"20#include "llvm/Support/MemoryBuffer.h"
21#include <vector>21#include <vector>
2222
23using llvm::object::Archive;
24using llvm::object::WasmObjectFile;
25using llvm::object::WasmSection;
26using llvm::object::WasmSymbol;
27using llvm::wasm::WasmGlobal;
28using llvm::wasm::WasmImport;
29using llvm::wasm::WasmRelocation;
30using llvm::wasm::WasmSignature;
31
32namespace llvm {
33namespace lto {
34class InputFile;
35}
36} // namespace llvm
37
38namespace lld {23namespace lld {
39namespace wasm {24namespace wasm {
4025
...@@ -42,6 +27,7 @@ class InputChunk;...@@ -42,6 +27,7 @@ class InputChunk;
42class InputFunction;27class InputFunction;
43class InputSegment;28class InputSegment;
44class InputGlobal;29class InputGlobal;
30class InputEvent;
45class InputSection;31class InputSection;
4632
47class InputFile {33class InputFile {
...@@ -84,12 +70,12 @@ public:...@@ -84,12 +70,12 @@ public:
84 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}70 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
85 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }71 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
8672
87 void addMember(const Archive::Symbol *Sym);73 void addMember(const llvm::object::Archive::Symbol *Sym);
8874
89 void parse() override;75 void parse() override;
9076
91private:77private:
92 std::unique_ptr<Archive> File;78 std::unique_ptr<llvm::object::Archive> File;
93 llvm::DenseSet<uint64_t> Seen;79 llvm::DenseSet<uint64_t> Seen;
94};80};
9581
...@@ -123,6 +109,7 @@ public:...@@ -123,6 +109,7 @@ public:
123 std::vector<InputSegment *> Segments;109 std::vector<InputSegment *> Segments;
124 std::vector<InputFunction *> Functions;110 std::vector<InputFunction *> Functions;
125 std::vector<InputGlobal *> Globals;111 std::vector<InputGlobal *> Globals;
112 std::vector<InputEvent *> Events;
126 std::vector<InputSection *> CustomSections;113 std::vector<InputSection *> CustomSections;
127 llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex;114 llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex;
128115
...@@ -131,6 +118,7 @@ public:...@@ -131,6 +118,7 @@ public:
131 DataSymbol *getDataSymbol(uint32_t Index) const;118 DataSymbol *getDataSymbol(uint32_t Index) const;
132 GlobalSymbol *getGlobalSymbol(uint32_t Index) const;119 GlobalSymbol *getGlobalSymbol(uint32_t Index) const;
133 SectionSymbol *getSectionSymbol(uint32_t Index) const;120 SectionSymbol *getSectionSymbol(uint32_t Index) const;
121 EventSymbol *getEventSymbol(uint32_t Index) const;
134122
135private:123private:
136 Symbol *createDefined(const WasmSymbol &Sym);124 Symbol *createDefined(const WasmSymbol &Sym);
deps/lld/wasm/InputGlobal.h-3
...@@ -16,9 +16,6 @@...@@ -16,9 +16,6 @@
16#include "lld/Common/ErrorHandler.h"16#include "lld/Common/ErrorHandler.h"
17#include "llvm/Object/Wasm.h"17#include "llvm/Object/Wasm.h"
1818
19using llvm::wasm::WasmGlobal;
20using llvm::wasm::WasmInitExpr;
21
22namespace lld {19namespace lld {
23namespace wasm {20namespace wasm {
2421
deps/lld/wasm/LTO.cpp+12-5
...@@ -36,8 +36,6 @@...@@ -36,8 +36,6 @@
36#include <vector>36#include <vector>
3737
38using namespace llvm;38using namespace llvm;
39using namespace llvm::object;
40
41using namespace lld;39using namespace lld;
42using namespace lld::wasm;40using namespace lld::wasm;
4341
...@@ -55,6 +53,14 @@ static std::unique_ptr<lto::LTO> createLTO() {...@@ -55,6 +53,14 @@ static std::unique_ptr<lto::LTO> createLTO() {
55 C.DisableVerify = Config->DisableVerify;53 C.DisableVerify = Config->DisableVerify;
56 C.DiagHandler = diagnosticHandler;54 C.DiagHandler = diagnosticHandler;
57 C.OptLevel = Config->LTOO;55 C.OptLevel = Config->LTOO;
56 C.MAttrs = GetMAttrs();
57
58 if (Config->Relocatable)
59 C.RelocModel = None;
60 else if (Config->Pic)
61 C.RelocModel = Reloc::PIC_;
62 else
63 C.RelocModel = Reloc::Static;
5864
59 if (Config->SaveTemps)65 if (Config->SaveTemps)
60 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",66 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
...@@ -72,10 +78,11 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}...@@ -72,10 +78,11 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
72BitcodeCompiler::~BitcodeCompiler() = default;78BitcodeCompiler::~BitcodeCompiler() = default;
7379
74static void undefine(Symbol *S) {80static void undefine(Symbol *S) {
75 if (isa<DefinedFunction>(S))81 if (auto F = dyn_cast<DefinedFunction>(S))
76 replaceSymbol<UndefinedFunction>(S, S->getName(), 0);82 replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
83 F->Signature);
77 else if (isa<DefinedData>(S))84 else if (isa<DefinedData>(S))
78 replaceSymbol<UndefinedData>(S, S->getName(), 0);85 replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
79 else86 else
80 llvm_unreachable("unexpected symbol kind");87 llvm_unreachable("unexpected symbol kind");
81}88}
deps/lld/wasm/MarkLive.cpp+4-2
...@@ -22,6 +22,7 @@...@@ -22,6 +22,7 @@
22#include "MarkLive.h"22#include "MarkLive.h"
23#include "Config.h"23#include "Config.h"
24#include "InputChunks.h"24#include "InputChunks.h"
25#include "InputEvent.h"
25#include "InputGlobal.h"26#include "InputGlobal.h"
26#include "SymbolTable.h"27#include "SymbolTable.h"
27#include "Symbols.h"28#include "Symbols.h"
...@@ -30,8 +31,6 @@...@@ -30,8 +31,6 @@
3031
31using namespace llvm;32using namespace llvm;
32using namespace llvm::wasm;33using namespace llvm::wasm;
33using namespace lld;
34using namespace lld::wasm;
3534
36void lld::wasm::markLive() {35void lld::wasm::markLive() {
37 if (!Config->GcSections)36 if (!Config->GcSections)
...@@ -107,6 +106,9 @@ void lld::wasm::markLive() {...@@ -107,6 +106,9 @@ void lld::wasm::markLive() {
107 for (InputGlobal *G : Obj->Globals)106 for (InputGlobal *G : Obj->Globals)
108 if (!G->Live)107 if (!G->Live)
109 message("removing unused section " + toString(G));108 message("removing unused section " + toString(G));
109 for (InputEvent *E : Obj->Events)
110 if (!E->Live)
111 message("removing unused section " + toString(E));
110 }112 }
111 for (InputChunk *C : Symtab->SyntheticFunctions)113 for (InputChunk *C : Symtab->SyntheticFunctions)
112 if (!C->Live)114 if (!C->Live)
deps/lld/wasm/Options.td+33-16
...@@ -6,9 +6,10 @@ class F<string name>: Flag<["--", "-"], name>;...@@ -6,9 +6,10 @@ class F<string name>: Flag<["--", "-"], name>;
6class J<string name>: Joined<["--", "-"], name>;6class J<string name>: Joined<["--", "-"], name>;
7class S<string name>: Separate<["--", "-"], name>;7class S<string name>: Separate<["--", "-"], name>;
88
9multiclass Eq<string name> {9multiclass Eq<string name, string help> {
10 def "": Separate<["--", "-"], name>;10 def NAME: Separate<["--", "-"], name>;
11 def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>;11 def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>,
12 HelpText<help>;
12}13}
1314
14multiclass B<string name, string help1, string help2> {15multiclass B<string name, string help1, string help2> {
...@@ -16,17 +17,24 @@ multiclass B<string name, string help1, string help2> {...@@ -16,17 +17,24 @@ multiclass B<string name, string help1, string help2> {
16 def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;17 def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
17}18}
1819
19// The follow flags are shared with the ELF linker20// The following flags are shared with the ELF linker
20def color_diagnostics: F<"color-diagnostics">,21def color_diagnostics: F<"color-diagnostics">,
21 HelpText<"Use colors in diagnostics">;22 HelpText<"Use colors in diagnostics">;
2223
23def color_diagnostics_eq: J<"color-diagnostics=">,24def color_diagnostics_eq: J<"color-diagnostics=">,
24 HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">;25 HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">;
2526
27def compress_relocations: F<"compress-relocations">,
28 HelpText<"Compress the relocation targets in the code section.">;
29
26defm demangle: B<"demangle",30defm demangle: B<"demangle",
27 "Demangle symbol names",31 "Demangle symbol names",
28 "Do not demangle symbol names">;32 "Do not demangle symbol names">;
2933
34defm export_dynamic: B<"export-dynamic",
35 "Put symbols in the dynamic symbol table",
36 "Do not put symbols in the dynamic symbol table (default)">;
37
30def entry: S<"entry">, MetaVarName<"<entry>">,38def entry: S<"entry">, MetaVarName<"<entry>">,
31 HelpText<"Name of entry point symbol">;39 HelpText<"Name of entry point symbol">;
3240
...@@ -67,20 +75,25 @@ def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,...@@ -67,20 +75,25 @@ def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
6775
68def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">;76def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">;
6977
78defm pie: B<"pie",
79 "Create a position independent executable",
80 "Do not create a position independent executable (default)">;
81
70defm print_gc_sections: B<"print-gc-sections",82defm print_gc_sections: B<"print-gc-sections",
71 "List removed unused sections",83 "List removed unused sections",
72 "Do not list removed unused sections">;84 "Do not list removed unused sections">;
7385
74def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;86def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
7587
88def shared: F<"shared">, HelpText<"Build a shared object">;
89
76def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;90def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
7791
78def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;92def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
7993
80def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;94def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
8195
82defm undefined: Eq<"undefined">,96defm undefined: Eq<"undefined", "Force undefined symbol during linking">;
83 HelpText<"Force undefined symbol during linking">;
8497
85def v: Flag<["-"], "v">, HelpText<"Display the version number">;98def v: Flag<["-"], "v">, HelpText<"Display the version number">;
8699
...@@ -102,8 +115,7 @@ def allow_undefined_file: J<"allow-undefined-file=">,...@@ -102,8 +115,7 @@ def allow_undefined_file: J<"allow-undefined-file=">,
102def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">,115def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">,
103 Alias<allow_undefined_file>;116 Alias<allow_undefined_file>;
104117
105defm export: Eq<"export">,118defm export: Eq<"export", "Force a symbol to be exported">;
106 HelpText<"Force a symbol to be exported">;
107119
108def export_all: F<"export-all">,120def export_all: F<"export-all">,
109 HelpText<"Export all symbols (normally combined with --no-gc-sections)">;121 HelpText<"Export all symbols (normally combined with --no-gc-sections)">;
...@@ -117,6 +129,9 @@ def global_base: J<"global-base=">,...@@ -117,6 +129,9 @@ def global_base: J<"global-base=">,
117def import_memory: F<"import-memory">,129def import_memory: F<"import-memory">,
118 HelpText<"Import memory from the environment">;130 HelpText<"Import memory from the environment">;
119131
132def shared_memory: F<"shared-memory">,
133 HelpText<"Use shared linear memory">;
134
120def import_table: F<"import-table">,135def import_table: F<"import-table">,
121 HelpText<"Import function table from the environment">;136 HelpText<"Import function table from the environment">;
122137
...@@ -137,12 +152,15 @@ defm whole_archive: B<"whole-archive",...@@ -137,12 +152,15 @@ defm whole_archive: B<"whole-archive",
137 "Do not force load of all members in a static library (default)">;152 "Do not force load of all members in a static library (default)">;
138153
139// Aliases154// Aliases
140def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;155def: JoinedOrSeparate<["-"], "e">, Alias<entry>;
141def alias_entry_entry: J<"entry=">, Alias<entry>;156def: J<"entry=">, Alias<entry>;
142def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>;157def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">;
143def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>;158def: Flag<["-"], "i">, Alias<initial_memory>;
144def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;159def: Flag<["-"], "m">, Alias<max_memory>;
145def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;160def: Flag<["-"], "r">, Alias<relocatable>;
161def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
162def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
163def: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
146164
147// LTO-related options.165// LTO-related options.
148def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,166def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
...@@ -153,6 +171,5 @@ def disable_verify: F<"disable-verify">;...@@ -153,6 +171,5 @@ def disable_verify: F<"disable-verify">;
153def save_temps: F<"save-temps">;171def save_temps: F<"save-temps">;
154def thinlto_cache_dir: J<"thinlto-cache-dir=">,172def thinlto_cache_dir: J<"thinlto-cache-dir=">,
155 HelpText<"Path to ThinLTO cached object file directory">;173 HelpText<"Path to ThinLTO cached object file directory">;
156defm thinlto_cache_policy: Eq<"thinlto-cache-policy">,174defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">;
157 HelpText<"Pruning policy for the ThinLTO cache">;
158def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;175def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
deps/lld/wasm/OutputSections.cpp+13-3
...@@ -40,6 +40,8 @@ static StringRef sectionTypeToString(uint32_t SectionType) {...@@ -40,6 +40,8 @@ static StringRef sectionTypeToString(uint32_t SectionType) {
40 return "MEMORY";40 return "MEMORY";
41 case WASM_SEC_GLOBAL:41 case WASM_SEC_GLOBAL:
42 return "GLOBAL";42 return "GLOBAL";
43 case WASM_SEC_EVENT:
44 return "EVENT";
43 case WASM_SEC_EXPORT:45 case WASM_SEC_EXPORT:
44 return "EXPORT";46 return "EXPORT";
45 case WASM_SEC_START:47 case WASM_SEC_START:
...@@ -136,9 +138,17 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments)...@@ -136,9 +138,17 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments)
136 for (OutputSegment *Segment : Segments) {138 for (OutputSegment *Segment : Segments) {
137 raw_string_ostream OS(Segment->Header);139 raw_string_ostream OS(Segment->Header);
138 writeUleb128(OS, 0, "memory index");140 writeUleb128(OS, 0, "memory index");
139 writeUleb128(OS, WASM_OPCODE_I32_CONST, "opcode:i32const");141 WasmInitExpr InitExpr;
140 writeSleb128(OS, Segment->StartVA, "memory offset");142 if (Config->Pic) {
141 writeUleb128(OS, WASM_OPCODE_END, "opcode:end");143 assert(Segments.size() <= 1 &&
144 "Currenly only a single data segment is supported in PIC mode");
145 InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
146 InitExpr.Value.Global = WasmSym::MemoryBase->getGlobalIndex();
147 } else {
148 InitExpr.Opcode = WASM_OPCODE_I32_CONST;
149 InitExpr.Value.Int32 = Segment->StartVA;
150 }
151 writeInitExpr(OS, InitExpr);
142 writeUleb128(OS, Segment->Size, "segment size");152 writeUleb128(OS, Segment->Size, "segment size");
143 OS.flush();153 OS.flush();
144154
deps/lld/wasm/OutputSections.h+3-5
...@@ -13,11 +13,9 @@...@@ -13,11 +13,9 @@
13#include "InputChunks.h"13#include "InputChunks.h"
14#include "WriterUtils.h"14#include "WriterUtils.h"
15#include "lld/Common/ErrorHandler.h"15#include "lld/Common/ErrorHandler.h"
16#include "lld/Common/LLVM.h"
16#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/DenseMap.h"
1718
18using llvm::raw_ostream;
19using llvm::raw_string_ostream;
20
21namespace lld {19namespace lld {
2220
23namespace wasm {21namespace wasm {
...@@ -82,7 +80,7 @@ public:...@@ -82,7 +80,7 @@ public:
82 std::string Body;80 std::string Body;
8381
84protected:82protected:
85 raw_string_ostream BodyOutputStream;83 llvm::raw_string_ostream BodyOutputStream;
86};84};
8785
88class CodeSection : public OutputSection {86class CodeSection : public OutputSection {
...@@ -113,7 +111,7 @@ protected:...@@ -113,7 +111,7 @@ protected:
113 size_t BodySize = 0;111 size_t BodySize = 0;
114};112};
115113
116// Represents a custom section in the output file. Wasm custom sections are 114// Represents a custom section in the output file. Wasm custom sections are
117// used for storing user-defined metadata. Unlike the core sections types115// used for storing user-defined metadata. Unlike the core sections types
118// they are identified by their string name.116// they are identified by their string name.
119// The linker combines custom sections that have the same name by simply117// The linker combines custom sections that have the same name by simply
deps/lld/wasm/OutputSegment.h+1-1
...@@ -26,7 +26,7 @@ public:...@@ -26,7 +26,7 @@ public:
26 void addInputSegment(InputSegment *InSeg) {26 void addInputSegment(InputSegment *InSeg) {
27 Alignment = std::max(Alignment, InSeg->getAlignment());27 Alignment = std::max(Alignment, InSeg->getAlignment());
28 InputSegments.push_back(InSeg);28 InputSegments.push_back(InSeg);
29 Size = llvm::alignTo(Size, InSeg->getAlignment());29 Size = llvm::alignTo(Size, 1 << InSeg->getAlignment());
30 InSeg->OutputSeg = this;30 InSeg->OutputSeg = this;
31 InSeg->OutputSegmentOffset = Size;31 InSeg->OutputSegmentOffset = Size;
32 Size += InSeg->getSize();32 Size += InSeg->getSize();
deps/lld/wasm/SymbolTable.cpp+88-59
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10#include "SymbolTable.h"10#include "SymbolTable.h"
11#include "Config.h"11#include "Config.h"
12#include "InputChunks.h"12#include "InputChunks.h"
13#include "InputEvent.h"
13#include "InputGlobal.h"14#include "InputGlobal.h"
14#include "WriterUtils.h"15#include "WriterUtils.h"
15#include "lld/Common/ErrorHandler.h"16#include "lld/Common/ErrorHandler.h"
...@@ -20,6 +21,7 @@...@@ -20,6 +21,7 @@
2021
21using namespace llvm;22using namespace llvm;
22using namespace llvm::wasm;23using namespace llvm::wasm;
24using namespace llvm::object;
23using namespace lld;25using namespace lld;
24using namespace lld::wasm;26using namespace lld::wasm;
2527
...@@ -60,7 +62,6 @@ void SymbolTable::addCombinedLTOObject() {...@@ -60,7 +62,6 @@ void SymbolTable::addCombinedLTOObject() {
60}62}
6163
62void SymbolTable::reportRemainingUndefines() {64void SymbolTable::reportRemainingUndefines() {
63 SetVector<Symbol *> Undefs;
64 for (Symbol *Sym : SymVector) {65 for (Symbol *Sym : SymVector) {
65 if (!Sym->isUndefined() || Sym->isWeak())66 if (!Sym->isUndefined() || Sym->isWeak())
66 continue;67 continue;
...@@ -68,34 +69,26 @@ void SymbolTable::reportRemainingUndefines() {...@@ -68,34 +69,26 @@ void SymbolTable::reportRemainingUndefines() {
68 continue;69 continue;
69 if (!Sym->IsUsedInRegularObj)70 if (!Sym->IsUsedInRegularObj)
70 continue;71 continue;
71 Undefs.insert(Sym);72 error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
72 }73 }
73
74 if (Undefs.empty())
75 return;
76
77 for (ObjFile *File : ObjectFiles)
78 for (Symbol *Sym : File->getSymbols())
79 if (Undefs.count(Sym))
80 error(toString(File) + ": undefined symbol: " + toString(*Sym));
81
82 for (Symbol *Sym : Undefs)
83 if (!Sym->getFile())
84 error("undefined symbol: " + toString(*Sym));
85}74}
8675
87Symbol *SymbolTable::find(StringRef Name) {76Symbol *SymbolTable::find(StringRef Name) {
88 return SymMap.lookup(CachedHashStringRef(Name));77 return SymMap.lookup(CachedHashStringRef(Name));
89}78}
9079
91std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {80std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
81 bool Inserted = false;
92 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];82 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
93 if (Sym)83 if (!Sym) {
94 return {Sym, false};84 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
95 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());85 Sym->IsUsedInRegularObj = false;
96 Sym->IsUsedInRegularObj = false;86 SymVector.emplace_back(Sym);
97 SymVector.emplace_back(Sym);87 Inserted = true;
98 return {Sym, true};88 }
89 if (!File || File->kind() == InputFile::ObjectKind)
90 Sym->IsUsedInRegularObj = true;
91 return {Sym, Inserted};
99}92}
10093
101static void reportTypeError(const Symbol *Existing, const InputFile *File,94static void reportTypeError(const Symbol *Existing, const InputFile *File,
...@@ -106,6 +99,8 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,...@@ -106,6 +99,8 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,
106 " in " + toString(File));99 " in " + toString(File));
107}100}
108101
102// Check the type of new symbol matches that of the symbol is replacing.
103// For functions this can also involve verifying that the signatures match.
109static void checkFunctionType(Symbol *Existing, const InputFile *File,104static void checkFunctionType(Symbol *Existing, const InputFile *File,
110 const WasmSignature *NewSig) {105 const WasmSignature *NewSig) {
111 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);106 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
...@@ -117,9 +112,9 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,...@@ -117,9 +112,9 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,
117 if (!NewSig)112 if (!NewSig)
118 return;113 return;
119114
120 const WasmSignature *OldSig = ExistingFunction->FunctionType;115 const WasmSignature *OldSig = ExistingFunction->Signature;
121 if (!OldSig) {116 if (!OldSig) {
122 ExistingFunction->FunctionType = NewSig;117 ExistingFunction->Signature = NewSig;
123 return;118 return;
124 }119 }
125120
...@@ -130,8 +125,6 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,...@@ -130,8 +125,6 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,
130 toString(*NewSig) + " in " + toString(File));125 toString(*NewSig) + " in " + toString(File));
131}126}
132127
133// Check the type of new symbol matches that of the symbol is replacing.
134// For functions this can also involve verifying that the signatures match.
135static void checkGlobalType(const Symbol *Existing, const InputFile *File,128static void checkGlobalType(const Symbol *Existing, const InputFile *File,
136 const WasmGlobalType *NewType) {129 const WasmGlobalType *NewType) {
137 if (!isa<GlobalSymbol>(Existing)) {130 if (!isa<GlobalSymbol>(Existing)) {
...@@ -147,6 +140,28 @@ static void checkGlobalType(const Symbol *Existing, const InputFile *File,...@@ -147,6 +140,28 @@ static void checkGlobalType(const Symbol *Existing, const InputFile *File,
147 }140 }
148}141}
149142
143static void checkEventType(const Symbol *Existing, const InputFile *File,
144 const WasmEventType *NewType,
145 const WasmSignature *NewSig) {
146 auto ExistingEvent = dyn_cast<EventSymbol>(Existing);
147 if (!isa<EventSymbol>(Existing)) {
148 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT);
149 return;
150 }
151
152 const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType();
153 const WasmSignature *OldSig = ExistingEvent->Signature;
154 if (NewType->Attribute != OldType->Attribute)
155 error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " +
156 toString(*OldType) + " in " + toString(Existing->getFile()) +
157 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
158 if (*NewSig != *OldSig)
159 warn("Event signature mismatch: " + Existing->getName() +
160 "\n>>> defined as " + toString(*OldSig) + " in " +
161 toString(Existing->getFile()) + "\n>>> defined as " +
162 toString(*NewSig) + " in " + toString(File));
163}
164
150static void checkDataType(const Symbol *Existing, const InputFile *File) {165static void checkDataType(const Symbol *Existing, const InputFile *File) {
151 if (!isa<DataSymbol>(Existing))166 if (!isa<DataSymbol>(Existing))
152 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);167 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
...@@ -158,15 +173,15 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,...@@ -158,15 +173,15 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
158 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");173 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
159 assert(!find(Name));174 assert(!find(Name));
160 SyntheticFunctions.emplace_back(Function);175 SyntheticFunctions.emplace_back(Function);
161 return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags,176 return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name,
162 nullptr, Function);177 Flags, nullptr, Function);
163}178}
164179
165DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,180DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
166 uint32_t Flags) {181 uint32_t Flags) {
167 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");182 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
168 assert(!find(Name));183 assert(!find(Name));
169 return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags);184 return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);
170}185}
171186
172DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,187DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
...@@ -175,8 +190,8 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,...@@ -175,8 +190,8 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
175 << "\n");190 << "\n");
176 assert(!find(Name));191 assert(!find(Name));
177 SyntheticGlobals.emplace_back(Global);192 SyntheticGlobals.emplace_back(Global);
178 return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr,193 return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags,
179 Global);194 nullptr, Global);
180}195}
181196
182static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,197static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
...@@ -210,13 +225,12 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,...@@ -210,13 +225,12 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
210Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,225Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
211 InputFile *File,226 InputFile *File,
212 InputFunction *Function) {227 InputFunction *Function) {
213 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");228 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
229 << (Function ? toString(Function->Signature) : "none")
230 << "]\n");
214 Symbol *S;231 Symbol *S;
215 bool WasInserted;232 bool WasInserted;
216 std::tie(S, WasInserted) = insert(Name);233 std::tie(S, WasInserted) = insert(Name, File);
217
218 if (!File || File->kind() == InputFile::ObjectKind)
219 S->IsUsedInRegularObj = true;
220234
221 if (WasInserted || S->isLazy()) {235 if (WasInserted || S->isLazy()) {
222 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);236 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
...@@ -226,8 +240,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,...@@ -226,8 +240,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
226 if (Function)240 if (Function)
227 checkFunctionType(S, File, &Function->Signature);241 checkFunctionType(S, File, &Function->Signature);
228242
229 if (shouldReplace(S, File, Flags))243 if (shouldReplace(S, File, Flags)) {
230 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);244 // If the new defined function doesn't have signture (i.e. bitcode
245 // functions) but the old symbols does then preserve the old signature
246 const WasmSignature *OldSig = nullptr;
247 if (auto* F = dyn_cast<FunctionSymbol>(S))
248 OldSig = F->Signature;
249 auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
250 if (!NewSym->Signature)
251 NewSym->Signature = OldSig;
252 }
231 return S;253 return S;
232}254}
233255
...@@ -238,10 +260,7 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,...@@ -238,10 +260,7 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
238 << "\n");260 << "\n");
239 Symbol *S;261 Symbol *S;
240 bool WasInserted;262 bool WasInserted;
241 std::tie(S, WasInserted) = insert(Name);263 std::tie(S, WasInserted) = insert(Name, File);
242
243 if (!File || File->kind() == InputFile::ObjectKind)
244 S->IsUsedInRegularObj = true;
245264
246 if (WasInserted || S->isLazy()) {265 if (WasInserted || S->isLazy()) {
247 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);266 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
...@@ -258,12 +277,10 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,...@@ -258,12 +277,10 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
258Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,277Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
259 InputFile *File, InputGlobal *Global) {278 InputFile *File, InputGlobal *Global) {
260 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");279 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
280
261 Symbol *S;281 Symbol *S;
262 bool WasInserted;282 bool WasInserted;
263 std::tie(S, WasInserted) = insert(Name);283 std::tie(S, WasInserted) = insert(Name, File);
264
265 if (!File || File->kind() == InputFile::ObjectKind)
266 S->IsUsedInRegularObj = true;
267284
268 if (WasInserted || S->isLazy()) {285 if (WasInserted || S->isLazy()) {
269 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);286 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
...@@ -277,17 +294,35 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,...@@ -277,17 +294,35 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
277 return S;294 return S;
278}295}
279296
297Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
298 InputFile *File, InputEvent *Event) {
299 LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n");
300
301 Symbol *S;
302 bool WasInserted;
303 std::tie(S, WasInserted) = insert(Name, File);
304
305 if (WasInserted || S->isLazy()) {
306 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
307 return S;
308 }
309
310 checkEventType(S, File, &Event->getType(), &Event->Signature);
311
312 if (shouldReplace(S, File, Flags))
313 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
314 return S;
315}
316
280Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,317Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
281 InputFile *File,318 InputFile *File,
282 const WasmSignature *Sig) {319 const WasmSignature *Sig) {
283 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");320 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
321 " [" << (Sig ? toString(*Sig) : "none") << "]\n");
284322
285 Symbol *S;323 Symbol *S;
286 bool WasInserted;324 bool WasInserted;
287 std::tie(S, WasInserted) = insert(Name);325 std::tie(S, WasInserted) = insert(Name, File);
288
289 if (!File || File->kind() == InputFile::ObjectKind)
290 S->IsUsedInRegularObj = true;
291326
292 if (WasInserted)327 if (WasInserted)
293 replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);328 replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
...@@ -305,10 +340,7 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,...@@ -305,10 +340,7 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
305340
306 Symbol *S;341 Symbol *S;
307 bool WasInserted;342 bool WasInserted;
308 std::tie(S, WasInserted) = insert(Name);343 std::tie(S, WasInserted) = insert(Name, File);
309
310 if (!File || File->kind() == InputFile::ObjectKind)
311 S->IsUsedInRegularObj = true;
312344
313 if (WasInserted)345 if (WasInserted)
314 replaceSymbol<UndefinedData>(S, Name, Flags, File);346 replaceSymbol<UndefinedData>(S, Name, Flags, File);
...@@ -326,10 +358,7 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,...@@ -326,10 +358,7 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
326358
327 Symbol *S;359 Symbol *S;
328 bool WasInserted;360 bool WasInserted;
329 std::tie(S, WasInserted) = insert(Name);361 std::tie(S, WasInserted) = insert(Name, File);
330
331 if (!File || File->kind() == InputFile::ObjectKind)
332 S->IsUsedInRegularObj = true;
333362
334 if (WasInserted)363 if (WasInserted)
335 replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);364 replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
...@@ -346,7 +375,7 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {...@@ -346,7 +375,7 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
346375
347 Symbol *S;376 Symbol *S;
348 bool WasInserted;377 bool WasInserted;
349 std::tie(S, WasInserted) = insert(Name);378 std::tie(S, WasInserted) = insert(Name, nullptr);
350379
351 if (WasInserted) {380 if (WasInserted) {
352 replaceSymbol<LazySymbol>(S, Name, File, *Sym);381 replaceSymbol<LazySymbol>(S, Name, File, *Sym);
deps/lld/wasm/SymbolTable.h+5-6
...@@ -13,12 +13,9 @@...@@ -13,12 +13,9 @@
13#include "InputFiles.h"13#include "InputFiles.h"
14#include "LTO.h"14#include "LTO.h"
15#include "Symbols.h"15#include "Symbols.h"
16#include "lld/Common/LLVM.h"
16#include "llvm/ADT/CachedHashString.h"17#include "llvm/ADT/CachedHashString.h"
17#include "llvm/ADT/DenseSet.h"18#include "llvm/ADT/DenseSet.h"
18#include "llvm/Support/raw_ostream.h"
19
20using llvm::wasm::WasmGlobalType;
21using llvm::wasm::WasmSignature;
2219
23namespace lld {20namespace lld {
24namespace wasm {21namespace wasm {
...@@ -59,6 +56,8 @@ public:...@@ -59,6 +56,8 @@ public:
59 uint32_t Size);56 uint32_t Size);
60 Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,57 Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
61 InputGlobal *G);58 InputGlobal *G);
59 Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
60 InputEvent *E);
6261
63 Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,62 Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
64 const WasmSignature *Signature);63 const WasmSignature *Signature);
...@@ -66,7 +65,7 @@ public:...@@ -66,7 +65,7 @@ public:
66 Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,65 Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
67 const WasmGlobalType *Type);66 const WasmGlobalType *Type);
6867
69 void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);68 void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym);
7069
71 bool addComdat(StringRef Name);70 bool addComdat(StringRef Name);
7271
...@@ -77,7 +76,7 @@ public:...@@ -77,7 +76,7 @@ public:
77 InputFunction *Function);76 InputFunction *Function);
7877
79private:78private:
80 std::pair<Symbol *, bool> insert(StringRef Name);79 std::pair<Symbol *, bool> insert(StringRef Name, InputFile *File);
8180
82 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;81 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
83 std::vector<Symbol *> SymVector;82 std::vector<Symbol *> SymVector;
deps/lld/wasm/Symbols.cpp+48-4
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10#include "Symbols.h"10#include "Symbols.h"
11#include "Config.h"11#include "Config.h"
12#include "InputChunks.h"12#include "InputChunks.h"
13#include "InputEvent.h"
13#include "InputFiles.h"14#include "InputFiles.h"
14#include "InputGlobal.h"15#include "InputGlobal.h"
15#include "OutputSegment.h"16#include "OutputSegment.h"
...@@ -27,7 +28,9 @@ DefinedFunction *WasmSym::CallCtors;...@@ -27,7 +28,9 @@ DefinedFunction *WasmSym::CallCtors;
27DefinedData *WasmSym::DsoHandle;28DefinedData *WasmSym::DsoHandle;
28DefinedData *WasmSym::DataEnd;29DefinedData *WasmSym::DataEnd;
29DefinedData *WasmSym::HeapBase;30DefinedData *WasmSym::HeapBase;
30DefinedGlobal *WasmSym::StackPointer;31GlobalSymbol *WasmSym::StackPointer;
32UndefinedGlobal *WasmSym::TableBase;
33UndefinedGlobal *WasmSym::MemoryBase;
3134
32WasmSymbolType Symbol::getWasmType() const {35WasmSymbolType Symbol::getWasmType() const {
33 if (isa<FunctionSymbol>(this))36 if (isa<FunctionSymbol>(this))
...@@ -36,6 +39,8 @@ WasmSymbolType Symbol::getWasmType() const {...@@ -36,6 +39,8 @@ WasmSymbolType Symbol::getWasmType() const {
36 return WASM_SYMBOL_TYPE_DATA;39 return WASM_SYMBOL_TYPE_DATA;
37 if (isa<GlobalSymbol>(this))40 if (isa<GlobalSymbol>(this))
38 return WASM_SYMBOL_TYPE_GLOBAL;41 return WASM_SYMBOL_TYPE_GLOBAL;
42 if (isa<EventSymbol>(this))
43 return WASM_SYMBOL_TYPE_EVENT;
39 if (isa<SectionSymbol>(this))44 if (isa<SectionSymbol>(this))
40 return WASM_SYMBOL_TYPE_SECTION;45 return WASM_SYMBOL_TYPE_SECTION;
41 llvm_unreachable("invalid symbol kind");46 llvm_unreachable("invalid symbol kind");
...@@ -52,6 +57,8 @@ InputChunk *Symbol::getChunk() const {...@@ -52,6 +57,8 @@ InputChunk *Symbol::getChunk() const {
52bool Symbol::isLive() const {57bool Symbol::isLive() const {
53 if (auto *G = dyn_cast<DefinedGlobal>(this))58 if (auto *G = dyn_cast<DefinedGlobal>(this))
54 return G->Global->Live;59 return G->Global->Live;
60 if (auto *E = dyn_cast<DefinedEvent>(this))
61 return E->Event->Live;
55 if (InputChunk *C = getChunk())62 if (InputChunk *C = getChunk())
56 return C->Live;63 return C->Live;
57 return Referenced;64 return Referenced;
...@@ -60,6 +67,8 @@ bool Symbol::isLive() const {...@@ -60,6 +67,8 @@ bool Symbol::isLive() const {
60void Symbol::markLive() {67void Symbol::markLive() {
61 if (auto *G = dyn_cast<DefinedGlobal>(this))68 if (auto *G = dyn_cast<DefinedGlobal>(this))
62 G->Global->Live = true;69 G->Global->Live = true;
70 if (auto *E = dyn_cast<DefinedEvent>(this))
71 E->Event->Live = true;
63 if (InputChunk *C = getChunk())72 if (InputChunk *C = getChunk())
64 C->Live = true;73 C->Live = true;
65 Referenced = true;74 Referenced = true;
...@@ -105,7 +114,10 @@ bool Symbol::isExported() const {...@@ -105,7 +114,10 @@ bool Symbol::isExported() const {
105 if (ForceExport || Config->ExportAll)114 if (ForceExport || Config->ExportAll)
106 return true;115 return true;
107116
108 return !isHidden();117 if (Config->ExportDynamic && !isHidden())
118 return true;
119
120 return false;
109}121}
110122
111uint32_t FunctionSymbol::getFunctionIndex() const {123uint32_t FunctionSymbol::getFunctionIndex() const {
...@@ -207,6 +219,32 @@ DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,...@@ -207,6 +219,32 @@ DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
207 Global ? &Global->getType() : nullptr),219 Global ? &Global->getType() : nullptr),
208 Global(Global) {}220 Global(Global) {}
209221
222uint32_t EventSymbol::getEventIndex() const {
223 if (auto *F = dyn_cast<DefinedEvent>(this))
224 return F->Event->getEventIndex();
225 assert(EventIndex != INVALID_INDEX);
226 return EventIndex;
227}
228
229void EventSymbol::setEventIndex(uint32_t Index) {
230 LLVM_DEBUG(dbgs() << "setEventIndex " << Name << " -> " << Index << "\n");
231 assert(EventIndex == INVALID_INDEX);
232 EventIndex = Index;
233}
234
235bool EventSymbol::hasEventIndex() const {
236 if (auto *F = dyn_cast<DefinedEvent>(this))
237 return F->Event->hasEventIndex();
238 return EventIndex != INVALID_INDEX;
239}
240
241DefinedEvent::DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
242 InputEvent *Event)
243 : EventSymbol(Name, DefinedEventKind, Flags, File,
244 Event ? &Event->getType() : nullptr,
245 Event ? &Event->Signature : nullptr),
246 Event(Event) {}
247
210uint32_t SectionSymbol::getOutputSectionIndex() const {248uint32_t SectionSymbol::getOutputSectionIndex() const {
211 LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");249 LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
212 assert(OutputSectionIndex != INVALID_INDEX);250 assert(OutputSectionIndex != INVALID_INDEX);
...@@ -223,10 +261,14 @@ void SectionSymbol::setOutputSectionIndex(uint32_t Index) {...@@ -223,10 +261,14 @@ void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
223void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }261void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
224262
225std::string lld::toString(const wasm::Symbol &Sym) {263std::string lld::toString(const wasm::Symbol &Sym) {
264 return lld::maybeDemangleSymbol(Sym.getName());
265}
266
267std::string lld::maybeDemangleSymbol(StringRef Name) {
226 if (Config->Demangle)268 if (Config->Demangle)
227 if (Optional<std::string> S = demangleItanium(Sym.getName()))269 if (Optional<std::string> S = demangleItanium(Name))
228 return *S;270 return *S;
229 return Sym.getName();271 return Name;
230}272}
231273
232std::string lld::toString(wasm::Symbol::Kind Kind) {274std::string lld::toString(wasm::Symbol::Kind Kind) {
...@@ -237,6 +279,8 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {...@@ -237,6 +279,8 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {
237 return "DefinedData";279 return "DefinedData";
238 case wasm::Symbol::DefinedGlobalKind:280 case wasm::Symbol::DefinedGlobalKind:
239 return "DefinedGlobal";281 return "DefinedGlobal";
282 case wasm::Symbol::DefinedEventKind:
283 return "DefinedEvent";
240 case wasm::Symbol::UndefinedFunctionKind:284 case wasm::Symbol::UndefinedFunctionKind:
241 return "UndefinedFunction";285 return "UndefinedFunction";
242 case wasm::Symbol::UndefinedDataKind:286 case wasm::Symbol::UndefinedDataKind:
deps/lld/wasm/Symbols.h+72-21
...@@ -15,21 +15,17 @@...@@ -15,21 +15,17 @@
15#include "llvm/Object/Archive.h"15#include "llvm/Object/Archive.h"
16#include "llvm/Object/Wasm.h"16#include "llvm/Object/Wasm.h"
1717
18using llvm::object::Archive;
19using llvm::object::WasmSymbol;
20using llvm::wasm::WasmGlobal;
21using llvm::wasm::WasmGlobalType;
22using llvm::wasm::WasmSignature;
23using llvm::wasm::WasmSymbolType;
24
25namespace lld {18namespace lld {
26namespace wasm {19namespace wasm {
2720
21using llvm::wasm::WasmSymbolType;
22
28class InputFile;23class InputFile;
29class InputChunk;24class InputChunk;
30class InputSegment;25class InputSegment;
31class InputFunction;26class InputFunction;
32class InputGlobal;27class InputGlobal;
28class InputEvent;
33class InputSection;29class InputSection;
3430
35#define INVALID_INDEX UINT32_MAX31#define INVALID_INDEX UINT32_MAX
...@@ -41,6 +37,7 @@ public:...@@ -41,6 +37,7 @@ public:
41 DefinedFunctionKind,37 DefinedFunctionKind,
42 DefinedDataKind,38 DefinedDataKind,
43 DefinedGlobalKind,39 DefinedGlobalKind,
40 DefinedEventKind,
44 SectionKind,41 SectionKind,
45 UndefinedFunctionKind,42 UndefinedFunctionKind,
46 UndefinedDataKind,43 UndefinedDataKind,
...@@ -52,7 +49,8 @@ public:...@@ -52,7 +49,8 @@ public:
5249
53 bool isDefined() const {50 bool isDefined() const {
54 return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind ||51 return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind ||
55 SymbolKind == DefinedGlobalKind || SymbolKind == SectionKind;52 SymbolKind == DefinedGlobalKind || SymbolKind == DefinedEventKind ||
53 SymbolKind == SectionKind;
56 }54 }
5755
58 bool isUndefined() const {56 bool isUndefined() const {
...@@ -126,12 +124,12 @@ public:...@@ -126,12 +124,12 @@ public:
126 void setFunctionIndex(uint32_t Index);124 void setFunctionIndex(uint32_t Index);
127 bool hasFunctionIndex() const;125 bool hasFunctionIndex() const;
128126
129 const WasmSignature *FunctionType;127 const WasmSignature *Signature;
130128
131protected:129protected:
132 FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,130 FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
133 const WasmSignature *Type)131 const WasmSignature *Sig)
134 : Symbol(Name, K, Flags, F), FunctionType(Type) {}132 : Symbol(Name, K, Flags, F), Signature(Sig) {}
135133
136 uint32_t TableIndex = INVALID_INDEX;134 uint32_t TableIndex = INVALID_INDEX;
137 uint32_t FunctionIndex = INVALID_INDEX;135 uint32_t FunctionIndex = INVALID_INDEX;
...@@ -245,8 +243,6 @@ protected:...@@ -245,8 +243,6 @@ protected:
245 const WasmGlobalType *GlobalType)243 const WasmGlobalType *GlobalType)
246 : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}244 : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
247245
248 // Explicit function type, needed for undefined or synthetic functions only.
249 // For regular defined globals this information comes from the InputChunk.
250 const WasmGlobalType *GlobalType;246 const WasmGlobalType *GlobalType;
251 uint32_t GlobalIndex = INVALID_INDEX;247 uint32_t GlobalIndex = INVALID_INDEX;
252};248};
...@@ -274,16 +270,61 @@ public:...@@ -274,16 +270,61 @@ public:
274 }270 }
275};271};
276272
273// Wasm events are features that suspend the current execution and transfer the
274// control flow to a corresponding handler. Currently the only supported event
275// kind is exceptions.
276//
277// Event tags are values to distinguish different events. For exceptions, they
278// can be used to distinguish different language's exceptions, i.e., all C++
279// exceptions have the same tag. Wasm can generate code capable of doing
280// different handling actions based on the tag of caught exceptions.
281//
282// A single EventSymbol object represents a single tag. C++ exception event
283// symbol is a weak symbol generated in every object file in which exceptions
284// are used, and has name '__cpp_exception' for linking.
285class EventSymbol : public Symbol {
286public:
287 static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
288
289 const WasmEventType *getEventType() const { return EventType; }
290
291 // Get/set the event index
292 uint32_t getEventIndex() const;
293 void setEventIndex(uint32_t Index);
294 bool hasEventIndex() const;
295
296 const WasmSignature *Signature;
297
298protected:
299 EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
300 const WasmEventType *EventType, const WasmSignature *Sig)
301 : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {}
302
303 const WasmEventType *EventType;
304 uint32_t EventIndex = INVALID_INDEX;
305};
306
307class DefinedEvent : public EventSymbol {
308public:
309 DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
310 InputEvent *Event);
311
312 static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
313
314 InputEvent *Event;
315};
316
277class LazySymbol : public Symbol {317class LazySymbol : public Symbol {
278public:318public:
279 LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym)319 LazySymbol(StringRef Name, InputFile *File,
320 const llvm::object::Archive::Symbol &Sym)
280 : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}321 : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
281322
282 static bool classof(const Symbol *S) { return S->kind() == LazyKind; }323 static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
283 void fetch();324 void fetch();
284325
285private:326private:
286 Archive::Symbol ArchiveSymbol;327 llvm::object::Archive::Symbol ArchiveSymbol;
287};328};
288329
289// linker-generated symbols330// linker-generated symbols
...@@ -291,7 +332,7 @@ struct WasmSym {...@@ -291,7 +332,7 @@ struct WasmSym {
291 // __stack_pointer332 // __stack_pointer
292 // Global that holds the address of the top of the explicit value stack in333 // Global that holds the address of the top of the explicit value stack in
293 // linear memory.334 // linear memory.
294 static DefinedGlobal *StackPointer;335 static GlobalSymbol *StackPointer;
295336
296 // __data_end337 // __data_end
297 // Symbol marking the end of the data and bss.338 // Symbol marking the end of the data and bss.
...@@ -310,6 +351,14 @@ struct WasmSym {...@@ -310,6 +351,14 @@ struct WasmSym {
310 // __dso_handle351 // __dso_handle
311 // Symbol used in calls to __cxa_atexit to determine current DLL352 // Symbol used in calls to __cxa_atexit to determine current DLL
312 static DefinedData *DsoHandle;353 static DefinedData *DsoHandle;
354
355 // __table_base
356 // Used in PIC code for offset of indirect function table
357 static UndefinedGlobal *TableBase;
358
359 // __memory_base
360 // Used in PIC code for offset of global data
361 static UndefinedGlobal *MemoryBase;
313};362};
314363
315// A buffer class that is large enough to hold any Symbol-derived364// A buffer class that is large enough to hold any Symbol-derived
...@@ -319,10 +368,11 @@ union SymbolUnion {...@@ -319,10 +368,11 @@ union SymbolUnion {
319 alignas(DefinedFunction) char A[sizeof(DefinedFunction)];368 alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
320 alignas(DefinedData) char B[sizeof(DefinedData)];369 alignas(DefinedData) char B[sizeof(DefinedData)];
321 alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];370 alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
322 alignas(LazySymbol) char D[sizeof(LazySymbol)];371 alignas(DefinedEvent) char D[sizeof(DefinedEvent)];
323 alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)];372 alignas(LazySymbol) char E[sizeof(LazySymbol)];
324 alignas(UndefinedData) char F[sizeof(UndefinedData)];373 alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)];
325 alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)];374 alignas(UndefinedData) char G[sizeof(UndefinedData)];
375 alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)];
326 alignas(SectionSymbol) char I[sizeof(SectionSymbol)];376 alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
327};377};
328378
...@@ -330,7 +380,7 @@ template <typename T, typename... ArgT>...@@ -330,7 +380,7 @@ template <typename T, typename... ArgT>
330T *replaceSymbol(Symbol *S, ArgT &&... Arg) {380T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331 static_assert(std::is_trivially_destructible<T>(),381 static_assert(std::is_trivially_destructible<T>(),
332 "Symbol types must be trivially destructible");382 "Symbol types must be trivially destructible");
333 static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");383 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
334 static_assert(alignof(T) <= alignof(SymbolUnion),384 static_assert(alignof(T) <= alignof(SymbolUnion),
335 "SymbolUnion not aligned enough");385 "SymbolUnion not aligned enough");
336 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&386 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
...@@ -349,6 +399,7 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) {...@@ -349,6 +399,7 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
349// Returns a symbol name for an error message.399// Returns a symbol name for an error message.
350std::string toString(const wasm::Symbol &Sym);400std::string toString(const wasm::Symbol &Sym);
351std::string toString(wasm::Symbol::Kind Kind);401std::string toString(wasm::Symbol::Kind Kind);
402std::string maybeDemangleSymbol(StringRef Name);
352403
353} // namespace lld404} // namespace lld
354405
deps/lld/wasm/Writer.cpp+155-35
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10#include "Writer.h"10#include "Writer.h"
11#include "Config.h"11#include "Config.h"
12#include "InputChunks.h"12#include "InputChunks.h"
13#include "InputEvent.h"
13#include "InputGlobal.h"14#include "InputGlobal.h"
14#include "OutputSections.h"15#include "OutputSections.h"
15#include "OutputSegment.h"16#include "OutputSegment.h"
...@@ -39,7 +40,6 @@ using namespace lld;...@@ -39,7 +40,6 @@ using namespace lld;
39using namespace lld::wasm;40using namespace lld::wasm;
4041
41static constexpr int kStackAlignment = 16;42static constexpr int kStackAlignment = 16;
42static constexpr int kInitialTableOffset = 1;
43static constexpr const char *kFunctionTableName = "__indirect_function_table";43static constexpr const char *kFunctionTableName = "__indirect_function_table";
4444
45namespace {45namespace {
...@@ -81,6 +81,7 @@ private:...@@ -81,6 +81,7 @@ private:
81 void createFunctionSection();81 void createFunctionSection();
82 void createTableSection();82 void createTableSection();
83 void createGlobalSection();83 void createGlobalSection();
84 void createEventSection();
84 void createExportSection();85 void createExportSection();
85 void createImportSection();86 void createImportSection();
86 void createMemorySection();87 void createMemorySection();
...@@ -90,6 +91,7 @@ private:...@@ -90,6 +91,7 @@ private:
90 void createCustomSections();91 void createCustomSections();
9192
92 // Custom sections93 // Custom sections
94 void createDylinkSection();
93 void createRelocSections();95 void createRelocSections();
94 void createLinkingSection();96 void createLinkingSection();
95 void createNameSection();97 void createNameSection();
...@@ -98,18 +100,25 @@ private:...@@ -98,18 +100,25 @@ private:
98 void writeSections();100 void writeSections();
99101
100 uint64_t FileSize = 0;102 uint64_t FileSize = 0;
103 uint32_t TableBase = 0;
101 uint32_t NumMemoryPages = 0;104 uint32_t NumMemoryPages = 0;
102 uint32_t MaxMemoryPages = 0;105 uint32_t MaxMemoryPages = 0;
106 // Memory size and aligment. Written to the "dylink" section
107 // when build with -shared or -pie.
108 uint32_t MemAlign = 0;
109 uint32_t MemSize = 0;
103110
104 std::vector<const WasmSignature *> Types;111 std::vector<const WasmSignature *> Types;
105 DenseMap<WasmSignature, int32_t> TypeIndices;112 DenseMap<WasmSignature, int32_t> TypeIndices;
106 std::vector<const Symbol *> ImportedSymbols;113 std::vector<const Symbol *> ImportedSymbols;
107 unsigned NumImportedFunctions = 0;114 unsigned NumImportedFunctions = 0;
108 unsigned NumImportedGlobals = 0;115 unsigned NumImportedGlobals = 0;
116 unsigned NumImportedEvents = 0;
109 std::vector<WasmExport> Exports;117 std::vector<WasmExport> Exports;
110 std::vector<const DefinedData *> DefinedFakeGlobals;118 std::vector<const DefinedData *> DefinedFakeGlobals;
111 std::vector<InputGlobal *> InputGlobals;119 std::vector<InputGlobal *> InputGlobals;
112 std::vector<InputFunction *> InputFunctions;120 std::vector<InputFunction *> InputFunctions;
121 std::vector<InputEvent *> InputEvents;
113 std::vector<const FunctionSymbol *> IndirectFunctions;122 std::vector<const FunctionSymbol *> IndirectFunctions;
114 std::vector<const Symbol *> SymtabEntries;123 std::vector<const Symbol *> SymtabEntries;
115 std::vector<WasmInitEntry> InitFunctions;124 std::vector<WasmInitEntry> InitFunctions;
...@@ -155,17 +164,19 @@ void Writer::createImportSection() {...@@ -155,17 +164,19 @@ void Writer::createImportSection() {
155 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;164 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
156 Import.Memory.Maximum = MaxMemoryPages;165 Import.Memory.Maximum = MaxMemoryPages;
157 }166 }
167 if (Config->SharedMemory)
168 Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
158 writeImport(OS, Import);169 writeImport(OS, Import);
159 }170 }
160171
161 if (Config->ImportTable) {172 if (Config->ImportTable) {
162 uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();173 uint32_t TableSize = TableBase + IndirectFunctions.size();
163 WasmImport Import;174 WasmImport Import;
164 Import.Module = "env";175 Import.Module = "env";
165 Import.Field = kFunctionTableName;176 Import.Field = kFunctionTableName;
166 Import.Kind = WASM_EXTERNAL_TABLE;177 Import.Kind = WASM_EXTERNAL_TABLE;
167 Import.Table.ElemType = WASM_TYPE_ANYFUNC;178 Import.Table.ElemType = WASM_TYPE_FUNCREF;
168 Import.Table.Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};179 Import.Table.Limits = {0, TableSize, 0};
169 writeImport(OS, Import);180 writeImport(OS, Import);
170 }181 }
171182
...@@ -175,11 +186,15 @@ void Writer::createImportSection() {...@@ -175,11 +186,15 @@ void Writer::createImportSection() {
175 Import.Field = Sym->getName();186 Import.Field = Sym->getName();
176 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {187 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
177 Import.Kind = WASM_EXTERNAL_FUNCTION;188 Import.Kind = WASM_EXTERNAL_FUNCTION;
178 Import.SigIndex = lookupType(*FunctionSym->FunctionType);189 Import.SigIndex = lookupType(*FunctionSym->Signature);
179 } else {190 } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
180 auto *GlobalSym = cast<GlobalSymbol>(Sym);
181 Import.Kind = WASM_EXTERNAL_GLOBAL;191 Import.Kind = WASM_EXTERNAL_GLOBAL;
182 Import.Global = *GlobalSym->getGlobalType();192 Import.Global = *GlobalSym->getGlobalType();
193 } else {
194 auto *EventSym = cast<EventSymbol>(Sym);
195 Import.Kind = WASM_EXTERNAL_EVENT;
196 Import.Event.Attribute = EventSym->getEventType()->Attribute;
197 Import.Event.SigIndex = lookupType(*EventSym->Signature);
183 }198 }
184 writeImport(OS, Import);199 writeImport(OS, Import);
185 }200 }
...@@ -214,8 +229,12 @@ void Writer::createMemorySection() {...@@ -214,8 +229,12 @@ void Writer::createMemorySection() {
214229
215 bool HasMax = MaxMemoryPages != 0;230 bool HasMax = MaxMemoryPages != 0;
216 writeUleb128(OS, 1, "memory count");231 writeUleb128(OS, 1, "memory count");
217 writeUleb128(OS, HasMax ? static_cast<unsigned>(WASM_LIMITS_FLAG_HAS_MAX) : 0,232 unsigned Flags = 0;
218 "memory limits flags");233 if (HasMax)
234 Flags |= WASM_LIMITS_FLAG_HAS_MAX;
235 if (Config->SharedMemory)
236 Flags |= WASM_LIMITS_FLAG_IS_SHARED;
237 writeUleb128(OS, Flags, "memory limits flags");
219 writeUleb128(OS, NumMemoryPages, "initial pages");238 writeUleb128(OS, NumMemoryPages, "initial pages");
220 if (HasMax)239 if (HasMax)
221 writeUleb128(OS, MaxMemoryPages, "max pages");240 writeUleb128(OS, MaxMemoryPages, "max pages");
...@@ -241,6 +260,31 @@ void Writer::createGlobalSection() {...@@ -241,6 +260,31 @@ void Writer::createGlobalSection() {
241 }260 }
242}261}
243262
263// The event section contains a list of declared wasm events associated with the
264// module. Currently the only supported event kind is exceptions. A single event
265// entry represents a single event with an event tag. All C++ exceptions are
266// represented by a single event. An event entry in this section contains
267// information on what kind of event it is (e.g. exception) and the type of
268// values contained in a single event object. (In wasm, an event can contain
269// multiple values of primitive types. But for C++ exceptions, we just throw a
270// pointer which is an i32 value (for wasm32 architecture), so the signature of
271// C++ exception is (i32)->(void), because all event types are assumed to have
272// void return type to share WasmSignature with functions.)
273void Writer::createEventSection() {
274 unsigned NumEvents = InputEvents.size();
275 if (NumEvents == 0)
276 return;
277
278 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EVENT);
279 raw_ostream &OS = Section->getStream();
280
281 writeUleb128(OS, NumEvents, "event count");
282 for (InputEvent *E : InputEvents) {
283 E->Event.Type.SigIndex = lookupType(E->Signature);
284 writeEvent(OS, E->Event);
285 }
286}
287
244void Writer::createTableSection() {288void Writer::createTableSection() {
245 if (Config->ImportTable)289 if (Config->ImportTable)
246 return;290 return;
...@@ -253,14 +297,14 @@ void Writer::createTableSection() {...@@ -253,14 +297,14 @@ void Writer::createTableSection() {
253 // no address-taken function will fail at validation time since it is297 // no address-taken function will fail at validation time since it is
254 // a validation error to include a call_indirect instruction if there298 // a validation error to include a call_indirect instruction if there
255 // is not table.299 // is not table.
256 uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();300 uint32_t TableSize = TableBase + IndirectFunctions.size();
257301
258 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);302 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
259 raw_ostream &OS = Section->getStream();303 raw_ostream &OS = Section->getStream();
260304
261 writeUleb128(OS, 1, "table count");305 writeUleb128(OS, 1, "table count");
262 WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};306 WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
263 writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits});307 writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
264}308}
265309
266void Writer::createExportSection() {310void Writer::createExportSection() {
...@@ -319,12 +363,17 @@ void Writer::createElemSection() {...@@ -319,12 +363,17 @@ void Writer::createElemSection() {
319 writeUleb128(OS, 1, "segment count");363 writeUleb128(OS, 1, "segment count");
320 writeUleb128(OS, 0, "table index");364 writeUleb128(OS, 0, "table index");
321 WasmInitExpr InitExpr;365 WasmInitExpr InitExpr;
322 InitExpr.Opcode = WASM_OPCODE_I32_CONST;366 if (Config->Pic) {
323 InitExpr.Value.Int32 = kInitialTableOffset;367 InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
368 InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
369 } else {
370 InitExpr.Opcode = WASM_OPCODE_I32_CONST;
371 InitExpr.Value.Int32 = TableBase;
372 }
324 writeInitExpr(OS, InitExpr);373 writeInitExpr(OS, InitExpr);
325 writeUleb128(OS, IndirectFunctions.size(), "elem count");374 writeUleb128(OS, IndirectFunctions.size(), "elem count");
326375
327 uint32_t TableIndex = kInitialTableOffset;376 uint32_t TableIndex = TableBase;
328 for (const FunctionSymbol *Sym : IndirectFunctions) {377 for (const FunctionSymbol *Sym : IndirectFunctions) {
329 assert(Sym->getTableIndex() == TableIndex);378 assert(Sym->getTableIndex() == TableIndex);
330 writeUleb128(OS, Sym->getFunctionIndex(), "function index");379 writeUleb128(OS, Sym->getFunctionIndex(), "function index");
...@@ -419,6 +468,21 @@ public:...@@ -419,6 +468,21 @@ public:
419 raw_string_ostream OS{Body};468 raw_string_ostream OS{Body};
420};469};
421470
471// Create the custom "dylink" section containing information for the dynamic
472// linker.
473// See
474// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
475void Writer::createDylinkSection() {
476 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink");
477 raw_ostream &OS = Section->getStream();
478
479 writeUleb128(OS, MemSize, "MemSize");
480 writeUleb128(OS, MemAlign, "MemAlign");
481 writeUleb128(OS, IndirectFunctions.size(), "TableSize");
482 writeUleb128(OS, 0, "TableAlign");
483 writeUleb128(OS, 0, "Needed"); // TODO: Support "needed" shared libraries
484}
485
422// Create the custom "linking" section containing linker metadata.486// Create the custom "linking" section containing linker metadata.
423// This is only created when relocatable output is requested.487// This is only created when relocatable output is requested.
424void Writer::createLinkingSection() {488void Writer::createLinkingSection() {
...@@ -448,6 +512,10 @@ void Writer::createLinkingSection() {...@@ -448,6 +512,10 @@ void Writer::createLinkingSection() {
448 writeUleb128(Sub.OS, G->getGlobalIndex(), "index");512 writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
449 if (Sym->isDefined())513 if (Sym->isDefined())
450 writeStr(Sub.OS, Sym->getName(), "sym name");514 writeStr(Sub.OS, Sym->getName(), "sym name");
515 } else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
516 writeUleb128(Sub.OS, E->getEventIndex(), "index");
517 if (Sym->isDefined())
518 writeStr(Sub.OS, Sym->getName(), "sym name");
451 } else if (isa<DataSymbol>(Sym)) {519 } else if (isa<DataSymbol>(Sym)) {
452 writeStr(Sub.OS, Sym->getName(), "sym name");520 writeStr(Sub.OS, Sym->getName(), "sym name");
453 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {521 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
...@@ -548,8 +616,7 @@ void Writer::createNameSection() {...@@ -548,8 +616,7 @@ void Writer::createNameSection() {
548 for (const Symbol *S : ImportedSymbols) {616 for (const Symbol *S : ImportedSymbols) {
549 if (auto *F = dyn_cast<FunctionSymbol>(S)) {617 if (auto *F = dyn_cast<FunctionSymbol>(S)) {
550 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");618 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
551 Optional<std::string> Name = demangleItanium(F->getName());619 writeStr(Sub.OS, toString(*S), "symbol name");
552 writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
553 }620 }
554 }621 }
555 for (const InputFunction *F : InputFunctions) {622 for (const InputFunction *F : InputFunctions) {
...@@ -558,8 +625,7 @@ void Writer::createNameSection() {...@@ -558,8 +625,7 @@ void Writer::createNameSection() {
558 if (!F->getDebugName().empty()) {625 if (!F->getDebugName().empty()) {
559 writeStr(Sub.OS, F->getDebugName(), "symbol name");626 writeStr(Sub.OS, F->getDebugName(), "symbol name");
560 } else {627 } else {
561 Optional<std::string> Name = demangleItanium(F->getName());628 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name");
562 writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
563 }629 }
564 }630 }
565 }631 }
...@@ -586,16 +652,16 @@ void Writer::writeSections() {...@@ -586,16 +652,16 @@ void Writer::writeSections() {
586// - heap start / unallocated652// - heap start / unallocated
587//653//
588// The --stack-first option means that stack is placed before any static data.654// The --stack-first option means that stack is placed before any static data.
589// This can be useful since it means that stack overflow traps immediately rather655// This can be useful since it means that stack overflow traps immediately
590// than overwriting global data, but also increases code size since all static656// rather than overwriting global data, but also increases code size since all
591// data loads and stores requires larger offsets.657// static data loads and stores requires larger offsets.
592void Writer::layoutMemory() {658void Writer::layoutMemory() {
593 createOutputSegments();659 createOutputSegments();
594660
595 uint32_t MemoryPtr = 0;661 uint32_t MemoryPtr = 0;
596662
597 auto PlaceStack = [&]() {663 auto PlaceStack = [&]() {
598 if (Config->Relocatable)664 if (Config->Relocatable || Config->Shared)
599 return;665 return;
600 MemoryPtr = alignTo(MemoryPtr, kStackAlignment);666 MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
601 if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))667 if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
...@@ -603,7 +669,8 @@ void Writer::layoutMemory() {...@@ -603,7 +669,8 @@ void Writer::layoutMemory() {
603 log("mem: stack size = " + Twine(Config->ZStackSize));669 log("mem: stack size = " + Twine(Config->ZStackSize));
604 log("mem: stack base = " + Twine(MemoryPtr));670 log("mem: stack base = " + Twine(MemoryPtr));
605 MemoryPtr += Config->ZStackSize;671 MemoryPtr += Config->ZStackSize;
606 WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;672 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
673 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
607 log("mem: stack top = " + Twine(MemoryPtr));674 log("mem: stack top = " + Twine(MemoryPtr));
608 };675 };
609676
...@@ -621,8 +688,10 @@ void Writer::layoutMemory() {...@@ -621,8 +688,10 @@ void Writer::layoutMemory() {
621 if (WasmSym::DsoHandle)688 if (WasmSym::DsoHandle)
622 WasmSym::DsoHandle->setVirtualAddress(DataStart);689 WasmSym::DsoHandle->setVirtualAddress(DataStart);
623690
691 MemAlign = 0;
624 for (OutputSegment *Seg : Segments) {692 for (OutputSegment *Seg : Segments) {
625 MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);693 MemAlign = std::max(MemAlign, Seg->Alignment);
694 MemoryPtr = alignTo(MemoryPtr, 1 << Seg->Alignment);
626 Seg->StartVA = MemoryPtr;695 Seg->StartVA = MemoryPtr;
627 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,696 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
628 MemoryPtr, Seg->Size, Seg->Alignment));697 MemoryPtr, Seg->Size, Seg->Alignment));
...@@ -635,6 +704,11 @@ void Writer::layoutMemory() {...@@ -635,6 +704,11 @@ void Writer::layoutMemory() {
635704
636 log("mem: static data = " + Twine(MemoryPtr - DataStart));705 log("mem: static data = " + Twine(MemoryPtr - DataStart));
637706
707 if (Config->Shared) {
708 MemSize = MemoryPtr;
709 return;
710 }
711
638 if (!Config->StackFirst)712 if (!Config->StackFirst)
639 PlaceStack();713 PlaceStack();
640714
...@@ -654,8 +728,8 @@ void Writer::layoutMemory() {...@@ -654,8 +728,8 @@ void Writer::layoutMemory() {
654 else728 else
655 MemoryPtr = Config->InitialMemory;729 MemoryPtr = Config->InitialMemory;
656 }730 }
657 uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize);731 MemSize = MemoryPtr;
658 NumMemoryPages = MemSize / WasmPageSize;732 NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
659 log("mem: total pages = " + Twine(NumMemoryPages));733 log("mem: total pages = " + Twine(NumMemoryPages));
660734
661 if (Config->MaxMemory != 0) {735 if (Config->MaxMemory != 0) {
...@@ -678,12 +752,15 @@ SyntheticSection *Writer::createSyntheticSection(uint32_t Type,...@@ -678,12 +752,15 @@ SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
678752
679void Writer::createSections() {753void Writer::createSections() {
680 // Known sections754 // Known sections
755 if (Config->Pic)
756 createDylinkSection();
681 createTypeSection();757 createTypeSection();
682 createImportSection();758 createImportSection();
683 createFunctionSection();759 createFunctionSection();
684 createTableSection();760 createTableSection();
685 createMemorySection();761 createMemorySection();
686 createGlobalSection();762 createGlobalSection();
763 createEventSection();
687 createExportSection();764 createExportSection();
688 createElemSection();765 createElemSection();
689 createCodeSection();766 createCodeSection();
...@@ -722,8 +799,10 @@ void Writer::calculateImports() {...@@ -722,8 +799,10 @@ void Writer::calculateImports() {
722 ImportedSymbols.emplace_back(Sym);799 ImportedSymbols.emplace_back(Sym);
723 if (auto *F = dyn_cast<FunctionSymbol>(Sym))800 if (auto *F = dyn_cast<FunctionSymbol>(Sym))
724 F->setFunctionIndex(NumImportedFunctions++);801 F->setFunctionIndex(NumImportedFunctions++);
802 else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
803 G->setGlobalIndex(NumImportedGlobals++);
725 else804 else
726 cast<GlobalSymbol>(Sym)->setGlobalIndex(NumImportedGlobals++);805 cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
727 }806 }
728}807}
729808
...@@ -759,6 +838,8 @@ void Writer::calculateExports() {...@@ -759,6 +838,8 @@ void Writer::calculateExports() {
759 continue;838 continue;
760 }839 }
761 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};840 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
841 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
842 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
762 } else {843 } else {
763 auto *D = cast<DefinedData>(Sym);844 auto *D = cast<DefinedData>(Sym);
764 DefinedFakeGlobals.emplace_back(D);845 DefinedFakeGlobals.emplace_back(D);
...@@ -836,6 +917,8 @@ void Writer::calculateTypes() {...@@ -836,6 +917,8 @@ void Writer::calculateTypes() {
836 // 1. Any signature used in the TYPE relocation917 // 1. Any signature used in the TYPE relocation
837 // 2. The signatures of all imported functions918 // 2. The signatures of all imported functions
838 // 3. The signatures of all defined functions919 // 3. The signatures of all defined functions
920 // 4. The signatures of all imported events
921 // 5. The signatures of all defined events
839922
840 for (ObjFile *File : Symtab->ObjectFiles) {923 for (ObjFile *File : Symtab->ObjectFiles) {
841 ArrayRef<WasmSignature> Types = File->getWasmObj()->types();924 ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
...@@ -844,16 +927,23 @@ void Writer::calculateTypes() {...@@ -844,16 +927,23 @@ void Writer::calculateTypes() {
844 File->TypeMap[I] = registerType(Types[I]);927 File->TypeMap[I] = registerType(Types[I]);
845 }928 }
846929
847 for (const Symbol *Sym : ImportedSymbols)930 for (const Symbol *Sym : ImportedSymbols) {
848 if (auto *F = dyn_cast<FunctionSymbol>(Sym))931 if (auto *F = dyn_cast<FunctionSymbol>(Sym))
849 registerType(*F->FunctionType);932 registerType(*F->Signature);
933 else if (auto *E = dyn_cast<EventSymbol>(Sym))
934 registerType(*E->Signature);
935 }
850936
851 for (const InputFunction *F : InputFunctions)937 for (const InputFunction *F : InputFunctions)
852 registerType(F->Signature);938 registerType(F->Signature);
939
940 for (const InputEvent *E : InputEvents)
941 registerType(E->Signature);
853}942}
854943
855void Writer::assignIndexes() {944void Writer::assignIndexes() {
856 uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();945 assert(InputFunctions.empty());
946 uint32_t FunctionIndex = NumImportedFunctions;
857 auto AddDefinedFunction = [&](InputFunction *Func) {947 auto AddDefinedFunction = [&](InputFunction *Func) {
858 if (!Func->Live)948 if (!Func->Live)
859 return;949 return;
...@@ -870,7 +960,7 @@ void Writer::assignIndexes() {...@@ -870,7 +960,7 @@ void Writer::assignIndexes() {
870 AddDefinedFunction(Func);960 AddDefinedFunction(Func);
871 }961 }
872962
873 uint32_t TableIndex = kInitialTableOffset;963 uint32_t TableIndex = TableBase;
874 auto HandleRelocs = [&](InputChunk *Chunk) {964 auto HandleRelocs = [&](InputChunk *Chunk) {
875 if (!Chunk->Live)965 if (!Chunk->Live)
876 return;966 return;
...@@ -902,7 +992,8 @@ void Writer::assignIndexes() {...@@ -902,7 +992,8 @@ void Writer::assignIndexes() {
902 HandleRelocs(P);992 HandleRelocs(P);
903 }993 }
904994
905 uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();995 assert(InputGlobals.empty());
996 uint32_t GlobalIndex = NumImportedGlobals;
906 auto AddDefinedGlobal = [&](InputGlobal *Global) {997 auto AddDefinedGlobal = [&](InputGlobal *Global) {
907 if (Global->Live) {998 if (Global->Live) {
908 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");999 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
...@@ -919,9 +1010,29 @@ void Writer::assignIndexes() {...@@ -919,9 +1010,29 @@ void Writer::assignIndexes() {
919 for (InputGlobal *Global : File->Globals)1010 for (InputGlobal *Global : File->Globals)
920 AddDefinedGlobal(Global);1011 AddDefinedGlobal(Global);
921 }1012 }
1013
1014 assert(InputEvents.empty());
1015 uint32_t EventIndex = NumImportedEvents;
1016 auto AddDefinedEvent = [&](InputEvent *Event) {
1017 if (Event->Live) {
1018 LLVM_DEBUG(dbgs() << "AddDefinedEvent: " << EventIndex << "\n");
1019 Event->setEventIndex(EventIndex++);
1020 InputEvents.push_back(Event);
1021 }
1022 };
1023
1024 for (ObjFile *File : Symtab->ObjectFiles) {
1025 LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
1026 for (InputEvent *Event : File->Events)
1027 AddDefinedEvent(Event);
1028 }
922}1029}
9231030
924static StringRef getOutputDataSegmentName(StringRef Name) {1031static StringRef getOutputDataSegmentName(StringRef Name) {
1032 // With PIC code we currently only support a single data segment since
1033 // we only have a single __memory_base to use as our base address.
1034 if (Config->Pic)
1035 return "data";
925 if (!Config->MergeDataSegments)1036 if (!Config->MergeDataSegments)
926 return Name;1037 return Name;
927 if (Name.startswith(".text."))1038 if (Name.startswith(".text."))
...@@ -930,6 +1041,8 @@ static StringRef getOutputDataSegmentName(StringRef Name) {...@@ -930,6 +1041,8 @@ static StringRef getOutputDataSegmentName(StringRef Name) {
930 return ".data";1041 return ".data";
931 if (Name.startswith(".bss."))1042 if (Name.startswith(".bss."))
932 return ".bss";1043 return ".bss";
1044 if (Name.startswith(".rodata."))
1045 return ".rodata";
933 return Name;1046 return Name;
934}1047}
9351048
...@@ -977,7 +1090,7 @@ void Writer::createCtorFunction() {...@@ -977,7 +1090,7 @@ void Writer::createCtorFunction() {
977 OS << BodyContent;1090 OS << BodyContent;
978 }1091 }
9791092
980 ArrayRef<uint8_t> Body = toArrayRef(Saver.save(FunctionBody));1093 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
981 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);1094 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
982}1095}
9831096
...@@ -989,7 +1102,7 @@ void Writer::calculateInitFunctions() {...@@ -989,7 +1102,7 @@ void Writer::calculateInitFunctions() {
989 const WasmLinkingData &L = File->getWasmObj()->linkingData();1102 const WasmLinkingData &L = File->getWasmObj()->linkingData();
990 for (const WasmInitFunc &F : L.InitFunctions) {1103 for (const WasmInitFunc &F : L.InitFunctions) {
991 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);1104 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
992 if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT})1105 if (*Sym->Signature != WasmSignature{{}, {}})
993 error("invalid signature for init func: " + toString(*Sym));1106 error("invalid signature for init func: " + toString(*Sym));
994 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});1107 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
995 }1108 }
...@@ -1004,9 +1117,14 @@ void Writer::calculateInitFunctions() {...@@ -1004,9 +1117,14 @@ void Writer::calculateInitFunctions() {
1004}1117}
10051118
1006void Writer::run() {1119void Writer::run() {
1007 if (Config->Relocatable)1120 if (Config->Relocatable || Config->Pic)
1008 Config->GlobalBase = 0;1121 Config->GlobalBase = 0;
10091122
1123 // For PIC code the table base is assigned dynamically by the loader.
1124 // For non-PIC, we start at 1 so that accessing table index 0 always traps.
1125 if (!Config->Pic)
1126 TableBase = 1;
1127
1010 log("-- calculateImports");1128 log("-- calculateImports");
1011 calculateImports();1129 calculateImports();
1012 log("-- assignIndexes");1130 log("-- assignIndexes");
...@@ -1029,8 +1147,10 @@ void Writer::run() {...@@ -1029,8 +1147,10 @@ void Writer::run() {
1029 if (errorHandler().Verbose) {1147 if (errorHandler().Verbose) {
1030 log("Defined Functions: " + Twine(InputFunctions.size()));1148 log("Defined Functions: " + Twine(InputFunctions.size()));
1031 log("Defined Globals : " + Twine(InputGlobals.size()));1149 log("Defined Globals : " + Twine(InputGlobals.size()));
1150 log("Defined Events : " + Twine(InputEvents.size()));
1032 log("Function Imports : " + Twine(NumImportedFunctions));1151 log("Function Imports : " + Twine(NumImportedFunctions));
1033 log("Global Imports : " + Twine(NumImportedGlobals));1152 log("Global Imports : " + Twine(NumImportedGlobals));
1153 log("Event Imports : " + Twine(NumImportedEvents));
1034 for (ObjFile *File : Symtab->ObjectFiles)1154 for (ObjFile *File : Symtab->ObjectFiles)
1035 File->dumpInfo();1155 File->dumpInfo();
1036 }1156 }
deps/lld/wasm/WriterUtils.cpp+43-39
...@@ -17,22 +17,6 @@...@@ -17,22 +17,6 @@
1717
18using namespace llvm;18using namespace llvm;
19using namespace llvm::wasm;19using namespace llvm::wasm;
20using namespace lld::wasm;
21
22static const char *valueTypeToString(uint8_t Type) {
23 switch (Type) {
24 case WASM_TYPE_I32:
25 return "i32";
26 case WASM_TYPE_I64:
27 return "i64";
28 case WASM_TYPE_F32:
29 return "f32";
30 case WASM_TYPE_F64:
31 return "f64";
32 default:
33 llvm_unreachable("invalid value type");
34 }
35}
3620
37namespace lld {21namespace lld {
3822
...@@ -73,21 +57,20 @@ void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {...@@ -73,21 +57,20 @@ void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
73 support::endian::write(OS, Number, support::little);57 support::endian::write(OS, Number, support::little);
74}58}
7559
76void wasm::writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg) {60void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
77 writeU8(OS, Type, Msg + "[type: " + valueTypeToString(Type) + "]");61 writeU8(OS, static_cast<uint8_t>(Type),
62 Msg + "[type: " + toString(Type) + "]");
78}63}
7964
80void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {65void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
81 writeU8(OS, WASM_TYPE_FUNC, "signature type");66 writeU8(OS, WASM_TYPE_FUNC, "signature type");
82 writeUleb128(OS, Sig.ParamTypes.size(), "param Count");67 writeUleb128(OS, Sig.Params.size(), "param Count");
83 for (uint8_t ParamType : Sig.ParamTypes) {68 for (ValType ParamType : Sig.Params) {
84 writeValueType(OS, ParamType, "param type");69 writeValueType(OS, ParamType, "param type");
85 }70 }
86 if (Sig.ReturnType == WASM_TYPE_NORESULT) {71 writeUleb128(OS, Sig.Returns.size(), "result Count");
87 writeUleb128(OS, 0, "result Count");72 if (Sig.Returns.size()) {
88 } else {73 writeValueType(OS, Sig.Returns[0], "result type");
89 writeUleb128(OS, 1, "result Count");
90 writeValueType(OS, Sig.ReturnType, "result type");
91 }74 }
92}75}
9376
...@@ -100,7 +83,7 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {...@@ -100,7 +83,7 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
100 case WASM_OPCODE_I64_CONST:83 case WASM_OPCODE_I64_CONST:
101 writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");84 writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
102 break;85 break;
103 case WASM_OPCODE_GET_GLOBAL:86 case WASM_OPCODE_GLOBAL_GET:
104 writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");87 writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
105 break;88 break;
106 default:89 default:
...@@ -117,7 +100,8 @@ void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {...@@ -117,7 +100,8 @@ void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
117}100}
118101
119void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {102void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
120 writeValueType(OS, Type.Type, "global type");103 // TODO: Update WasmGlobalType to use ValType and remove this cast.
104 writeValueType(OS, ValType(Type.Type), "global type");
121 writeU8(OS, Type.Mutable, "global mutable");105 writeU8(OS, Type.Mutable, "global mutable");
122}106}
123107
...@@ -126,8 +110,17 @@ void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {...@@ -126,8 +110,17 @@ void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
126 writeInitExpr(OS, Global.InitExpr);110 writeInitExpr(OS, Global.InitExpr);
127}111}
128112
113void wasm::writeEventType(raw_ostream &OS, const WasmEventType &Type) {
114 writeUleb128(OS, Type.Attribute, "event attribute");
115 writeUleb128(OS, Type.SigIndex, "sig index");
116}
117
118void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) {
119 writeEventType(OS, Event.Type);
120}
121
129void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {122void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
130 writeU8(OS, WASM_TYPE_ANYFUNC, "table type");123 writeU8(OS, WASM_TYPE_FUNCREF, "table type");
131 writeLimits(OS, Type.Limits);124 writeLimits(OS, Type.Limits);
132}125}
133126
...@@ -142,6 +135,9 @@ void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {...@@ -142,6 +135,9 @@ void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
142 case WASM_EXTERNAL_GLOBAL:135 case WASM_EXTERNAL_GLOBAL:
143 writeGlobalType(OS, Import.Global);136 writeGlobalType(OS, Import.Global);
144 break;137 break;
138 case WASM_EXTERNAL_EVENT:
139 writeEventType(OS, Import.Event);
140 break;
145 case WASM_EXTERNAL_MEMORY:141 case WASM_EXTERNAL_MEMORY:
146 writeLimits(OS, Import.Memory);142 writeLimits(OS, Import.Memory);
147 break;143 break;
...@@ -178,13 +174,15 @@ void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {...@@ -178,13 +174,15 @@ void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
178std::string lld::toString(ValType Type) {174std::string lld::toString(ValType Type) {
179 switch (Type) {175 switch (Type) {
180 case ValType::I32:176 case ValType::I32:
181 return "I32";177 return "i32";
182 case ValType::I64:178 case ValType::I64:
183 return "I64";179 return "i64";
184 case ValType::F32:180 case ValType::F32:
185 return "F32";181 return "f32";
186 case ValType::F64:182 case ValType::F64:
187 return "F64";183 return "f64";
184 case ValType::V128:
185 return "v128";
188 case ValType::EXCEPT_REF:186 case ValType::EXCEPT_REF:
189 return "except_ref";187 return "except_ref";
190 }188 }
...@@ -193,20 +191,26 @@ std::string lld::toString(ValType Type) {...@@ -193,20 +191,26 @@ std::string lld::toString(ValType Type) {
193191
194std::string lld::toString(const WasmSignature &Sig) {192std::string lld::toString(const WasmSignature &Sig) {
195 SmallString<128> S("(");193 SmallString<128> S("(");
196 for (uint32_t Type : Sig.ParamTypes) {194 for (ValType Type : Sig.Params) {
197 if (S.size() != 1)195 if (S.size() != 1)
198 S += ", ";196 S += ", ";
199 S += toString(static_cast<ValType>(Type));197 S += toString(Type);
200 }198 }
201 S += ") -> ";199 S += ") -> ";
202 if (Sig.ReturnType == WASM_TYPE_NORESULT)200 if (Sig.Returns.size() == 0)
203 S += "void";201 S += "void";
204 else202 else
205 S += toString(static_cast<ValType>(Sig.ReturnType));203 S += toString(Sig.Returns[0]);
206 return S.str();204 return S.str();
207}205}
208206
209std::string lld::toString(const WasmGlobalType &Sig) {207std::string lld::toString(const WasmGlobalType &Type) {
210 return (Sig.Mutable ? "var " : "const ") +208 return (Type.Mutable ? "var " : "const ") +
211 toString(static_cast<ValType>(Sig.Type));209 toString(static_cast<ValType>(Type.Type));
210}
211
212std::string lld::toString(const WasmEventType &Type) {
213 if (Type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION)
214 return "exception";
215 return "unknown";
212}216}
deps/lld/wasm/WriterUtils.h+8-5
...@@ -13,9 +13,6 @@...@@ -13,9 +13,6 @@
13#include "lld/Common/LLVM.h"13#include "lld/Common/LLVM.h"
14#include "llvm/ADT/Twine.h"14#include "llvm/ADT/Twine.h"
15#include "llvm/Object/Wasm.h"15#include "llvm/Object/Wasm.h"
16#include "llvm/Support/raw_ostream.h"
17
18using llvm::raw_ostream;
1916
20namespace lld {17namespace lld {
21namespace wasm {18namespace wasm {
...@@ -35,7 +32,8 @@ void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg);...@@ -35,7 +32,8 @@ void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg);
3532
36void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg);33void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg);
3734
38void writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg);35void writeValueType(raw_ostream &OS, llvm::wasm::ValType Type,
36 const Twine &Msg);
3937
40void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig);38void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig);
4139
...@@ -47,6 +45,10 @@ void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type);...@@ -47,6 +45,10 @@ void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type);
4745
48void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global);46void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global);
4947
48void writeEventType(raw_ostream &OS, const llvm::wasm::WasmEventType &Type);
49
50void writeEvent(raw_ostream &OS, const llvm::wasm::WasmEvent &Event);
51
50void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type);52void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type);
5153
52void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import);54void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import);
...@@ -57,7 +59,8 @@ void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export);...@@ -57,7 +59,8 @@ void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export);
5759
58std::string toString(llvm::wasm::ValType Type);60std::string toString(llvm::wasm::ValType Type);
59std::string toString(const llvm::wasm::WasmSignature &Sig);61std::string toString(const llvm::wasm::WasmSignature &Sig);
60std::string toString(const llvm::wasm::WasmGlobalType &Sig);62std::string toString(const llvm::wasm::WasmGlobalType &Type);
63std::string toString(const llvm::wasm::WasmEventType &Type);
6164
62} // namespace lld65} // namespace lld
6366