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
signature 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()
113113 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp"
114114 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp"
115115 )
116
116117 set(EMBEDDED_LLD_ELF_SOURCES
117118 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/AArch64ErrataFix.cpp"
118119 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp"
......@@ -120,19 +121,21 @@ else()
120121 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/ARM.cpp"
121122 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AVR.cpp"
122123 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Hexagon.cpp"
124 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MSP430.cpp"
123125 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Mips.cpp"
124126 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MipsArchTree.cpp"
125127 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp"
126128 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp"
129 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/RISCV.cpp"
127130 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp"
128131 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86.cpp"
129132 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp"
130133 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/CallGraphSort.cpp"
134 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DWARF.cpp"
131135 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp"
132136 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp"
133137 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp"
134138 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp"
135 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/GdbIndex.cpp"
136139 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp"
137140 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp"
138141 "${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
5555 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)
5656OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
5757 "Use colors in diagnostics", nullptr, nullptr)
58OPTION(prefix_1, "debug:dwarf", debug_dwarf, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
59OPTION(prefix_1, "debug:full", debug_full, Flag, INVALID, debug, nullptr, 0, 0, nullptr, 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)
58OPTION(prefix_1, "debug:", debug_opt, Joined, INVALID, INVALID, nullptr, 0, 0,
59 "Embed a symbol table in the image with option", nullptr, nullptr)
6260OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0,
6361 "Debug Info Options", nullptr, nullptr)
6462OPTION(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,
9593 "Enable base relocations (default)", nullptr, nullptr)
9694OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0,
9795 "Disable base relocations", nullptr, nullptr)
98OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
99OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0,
96OPTION(prefix_1, "force:multiple", force_multiple, 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,
10099 "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)
101102OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
102103OPTION(prefix_1, "guard:", guard, Joined, INVALID, INVALID, nullptr, 0, 0,
103104 "Control flow guard", nullptr, nullptr)
......@@ -148,30 +149,32 @@ OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr,
148149OPTION(prefix_1, "machine:", machine, Joined, INVALID, INVALID, nullptr, 0, 0,
149150 "Specify target platform", nullptr, nullptr)
150151OPTION(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)
152153OPTION(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)
154155OPTION(prefix_1, "manifestfile:", manifestfile, Joined, INVALID, INVALID, nullptr, 0, 0,
155 "Manifest file path", nullptr, nullptr)
156 "Manifest output path, with /manifest", nullptr, nullptr)
156157OPTION(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)
158159OPTION(prefix_1, "manifestuac:", manifestuac, Joined, INVALID, INVALID, nullptr, 0, 0,
159160 "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)
161163OPTION(prefix_1, "maxilksize:", maxilksize, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
162164OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0,
163165 "Combine sections", nullptr, nullptr)
164166OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0,
165167 "Options to pass to LLVM", nullptr, nullptr)
166OPTION(prefix_1, "msvclto", msvclto, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
167168OPTION(prefix_1, "natvis:", natvis, Joined, INVALID, INVALID, nullptr, 0, 0,
168169 "Path to natvis file to embed in the PDB", nullptr, nullptr)
169170OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
170171 "Do not use colors in diagnostics", nullptr, nullptr)
171172OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,
172173 "Remove a default library", nullptr, nullptr)
173OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
174OPTION(prefix_1, "noentry", noentry, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
174OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0,
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)
175178OPTION(prefix_1, "nologo", nologo, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
176179OPTION(prefix_1, "nxcompat:no", nxcompat_no, Flag, INVALID, INVALID, nullptr, 0, 0,
177180 "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,
6262OPTION(prefix_2, "call-graph-ordering-file=", call_graph_ordering_file_eq, Joined, INVALID, call_graph_ordering_file, nullptr, 0, 0,
6363 "Layout sections to optimize the given callgraph", nullptr, nullptr)
6464OPTION(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)
6567OPTION(prefix_2, "call_shared", anonymous_1, Flag, INVALID, Bdynamic, nullptr, 0, 0,
6668 "Alias for --Bdynamic", nullptr, nullptr)
6769OPTION(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
133135 "Exclude static libraries from automatic export", nullptr, nullptr)
134136OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
135137OPTION(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)
137139OPTION(prefix_2, "export-dynamic-symbol=", export_dynamic_symbol_eq, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0,
138140 "Put a symbol in the dynamic symbol table", nullptr, nullptr)
139141OPTION(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
245247 "Do not apply link-time values for dynamic relocations (default)", nullptr, nullptr)
246248OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
247249 "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)
248252OPTION(prefix_2, "no-check-sections", no_check_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
249253 "Do not check section addresses for overlaps", nullptr, nullptr)
250254OPTION(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,
291295 "Do not put read-only non-executable sections in their own segment", nullptr, nullptr)
292296OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,
293297 "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)
294300OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0,
295301 "Report version scripts that refer undefined symbols", nullptr, nullptr)
296302OPTION(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
301307 "Do not warn about backward symbol references to fetch archive members (default)", nullptr, nullptr)
302308OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
303309 "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)
304312OPTION(prefix_2, "no-warn-mismatch", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
305313OPTION(prefix_2, "no-warn-symbol-ordering", no_warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,
306314 "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
338346OPTION(prefix_2, "pack-dyn-relocs", pack_dyn_relocs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,android,relr,android+relr]", nullptr)
339347OPTION(prefix_2, "pic-executable", anonymous_23, Flag, INVALID, pie, nullptr, 0, 0,
340348 "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)
341351OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
342352 "Create a position independent executable", nullptr, nullptr)
343353OPTION(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
349359 "Alias for -disable-verify", nullptr, nullptr)
350360OPTION(prefix_2, "plugin-opt=dwo_dir=", plugin_opt_dwo_dir_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
351361 "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)
352363OPTION(prefix_2, "plugin-opt=jobs=", anonymous_42, Joined, INVALID, thinlto_jobs, nullptr, 0, 0,
353364 "Alias for -thinlto-jobs", nullptr, nullptr)
354365OPTION(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
424435OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0,
425436 "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr)
426437OPTION(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)
427441OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0,
428442 "Ignored for compatibility with GNU unless you pass --warn-backrefs", nullptr, nullptr)
429443OPTION(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
467481 "Number of ThinLTO jobs", nullptr, nullptr)
468482OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
469483 "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)
470486OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0,
471487 "Trace references to symbols", nullptr, nullptr)
472488OPTION(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
511527OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
512528 "Warn about duplicate common symbols", nullptr, nullptr)
513529OPTION(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)
514532OPTION(prefix_2, "warn-once", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
515533OPTION(prefix_2, "warn-shared-textrel", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
516534OPTION(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,
9090OPTION(prefix_2, "pdb", pdb, Separate, INVALID, INVALID, nullptr, 0, 0,
9191 "Specify output PDB debug information file", nullptr, nullptr)
9292OPTION(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)
93100OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
94101 "Build a shared object", nullptr, nullptr)
95102OPTION(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#define LLD_VERSION 7.0.0
2#define LLD_VERSION_STRING "7.0.0"
3#define LLD_VERSION_MAJOR 7
1#define LLD_VERSION 8.0.0
2#define LLD_VERSION_STRING "8.0.0"
3#define LLD_VERSION_MAJOR 8
44#define LLD_VERSION_MINOR 0
55#define LLD_REVISION_STRING ""
66#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
3636 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)
3737OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
3838 "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)
3941OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
4042 "Demangle symbol names", nullptr, nullptr)
4143OPTION(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)
4345OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,
4446 "Name of entry point symbol", "<entry>", nullptr)
4547OPTION(prefix_1, "error-limit=", error_limit, Joined, INVALID, INVALID, nullptr, 0, 0,
4648 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)
4749OPTION(prefix_1, "export-all", export_all, Flag, INVALID, INVALID, nullptr, 0, 0,
4850 "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)
4953OPTION(prefix_1, "export-table", export_table, Flag, INVALID, INVALID, nullptr, 0, 0,
5054 "Export function table to the environment", nullptr, nullptr)
5155OPTION(prefix_1, "export=", export_eq, Joined, INVALID, export, nullptr, 0, 0,
5256 "Force a symbol to be exported", nullptr, nullptr)
53OPTION(prefix_1, "export", export, Separate, INVALID, INVALID, nullptr, 0, 0,
54 "Force a symbol to be exported", nullptr, nullptr)
55OPTION(prefix_2, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
57OPTION(prefix_1, "export", export, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
58OPTION(prefix_2, "E", anonymous_2, Flag, INVALID, export_dynamic, nullptr, 0, 0,
59 "Alias for --export-dynamic", nullptr, nullptr)
60OPTION(prefix_2, "e", anonymous_0, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
5661OPTION(prefix_1, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0,
5762 "Treat warnings as errors", nullptr, nullptr)
5863OPTION(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,
6772 "Import function table from the environment", nullptr, nullptr)
6873OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0,
6974 "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)
7176OPTION(prefix_1, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0,
7277 "Optimization level for LTO", "<opt-level>", nullptr)
7378OPTION(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
8287 "Enable merging data segments", nullptr, nullptr)
8388OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0,
8489 "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)
8691OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
8792 "Do not use colors in diagnostics", nullptr, nullptr)
8893OPTION(prefix_1, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
8994 "Do not demangle symbol names", nullptr, nullptr)
9095OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0,
9196 "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)
9299OPTION(prefix_1, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93100OPTION(prefix_1, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
94101 "Disable garbage collection of unused sections", nullptr, nullptr)
95102OPTION(prefix_1, "no-merge-data-segments", no_merge_data_segments, Flag, INVALID, INVALID, nullptr, 0, 0,
96103 "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)
97106OPTION(prefix_1, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
98107 "Do not list removed unused sections", nullptr, nullptr)
99108OPTION(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,
104113 "Optimize output file size", nullptr, nullptr)
105114OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
106115 "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)
107118OPTION(prefix_1, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
108119 "List removed unused sections", nullptr, nullptr)
109120OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,
110121 "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)
112123OPTION(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)
113128OPTION(prefix_1, "stack-first", stack_first, Flag, INVALID, INVALID, nullptr, 0, 0,
114129 "Place stack at start of linear memory rather than after data", nullptr, nullptr)
115130OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,
116131 "Strip all symbols", nullptr, nullptr)
117132OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,
118133 "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)
119138OPTION(prefix_1, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0,
120139 "Path to ThinLTO cached object file directory", nullptr, nullptr)
121140OPTION(prefix_1, "thinlto-cache-policy=", thinlto_cache_policy_eq, Joined, INVALID, thinlto_cache_policy, nullptr, 0, 0,
122141 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
123OPTION(prefix_1, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0,
124 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
142OPTION(prefix_1, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
125143OPTION(prefix_1, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0,
126144 "Number of ThinLTO jobs", nullptr, nullptr)
127145OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
128146 "Run the linker multi-threaded", nullptr, nullptr)
129147OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0,
130148 "Force undefined symbol during linking", nullptr, nullptr)
131OPTION(prefix_1, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0,
132 "Force undefined symbol during linking", nullptr, nullptr)
133OPTION(prefix_2, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
149OPTION(prefix_1, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
150OPTION(prefix_2, "u", anonymous_8, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
134151OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
135152 "Verbose mode", nullptr, nullptr)
136153OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
deps/lld/COFF/Chunks.cpp+293-54
......@@ -11,6 +11,7 @@
1111#include "InputFiles.h"
1212#include "Symbols.h"
1313#include "Writer.h"
14#include "SymbolTable.h"
1415#include "lld/Common/ErrorHandler.h"
1516#include "llvm/ADT/Twine.h"
1617#include "llvm/BinaryFormat/COFF.h"
......@@ -44,6 +45,22 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
4445 Live = !Config->DoGC || !isCOMDAT();
4546}
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
4764static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
4865static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
4966static 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) {
5875 return true;
5976 if (Sec->isCodeView())
6077 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;
6280}
6381
6482static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
......@@ -98,7 +116,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
98116 case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;
99117 case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;
100118 default:
101 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
119 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
102120 toString(File));
103121 }
104122}
......@@ -113,7 +131,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
113131 case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;
114132 case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;
115133 default:
116 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
134 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
117135 toString(File));
118136 }
119137}
......@@ -123,16 +141,22 @@ static void applyMOV(uint8_t *Off, uint16_t V) {
123141 write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
124142}
125143
126static uint16_t readMOV(uint8_t *Off) {
144static uint16_t readMOV(uint8_t *Off, bool MOVT) {
127145 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");
128149 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");
129153 return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
130154 ((Op1 & 0x000f) << 12);
131155}
132156
133157void applyMOV32T(uint8_t *Off, uint32_t V) {
134 uint16_t ImmW = readMOV(Off); // read MOVW operand
135 uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
158 uint16_t ImmW = readMOV(Off, false); // read MOVW operand
159 uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
136160 uint32_t Imm = ImmW | (ImmT << 16);
137161 V += Imm; // add the immediate offset
138162 applyMOV(Off, V); // set MOVW operand
......@@ -141,7 +165,7 @@ void applyMOV32T(uint8_t *Off, uint32_t V) {
141165
142166static void applyBranch20T(uint8_t *Off, int32_t V) {
143167 if (!isInt<21>(V))
144 fatal("relocation out of range");
168 error("relocation out of range");
145169 uint32_t S = V < 0 ? 1 : 0;
146170 uint32_t J1 = (V >> 19) & 1;
147171 uint32_t J2 = (V >> 18) & 1;
......@@ -151,7 +175,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) {
151175
152176void applyBranch24T(uint8_t *Off, int32_t V) {
153177 if (!isInt<25>(V))
154 fatal("relocation out of range");
178 error("relocation out of range");
155179 uint32_t S = V < 0 ? 1 : 0;
156180 uint32_t J1 = ((~V >> 23) & 1) ^ S;
157181 uint32_t J2 = ((~V >> 22) & 1) ^ S;
......@@ -176,7 +200,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
176200 case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
177201 case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
178202 default:
179 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
203 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
180204 toString(File));
181205 }
182206}
......@@ -184,7 +208,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
184208// Interpret the existing immediate value as a byte offset to the
185209// target symbol, then update the instruction with the immediate as
186210// 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) {
188212 uint32_t Orig = read32le(Off);
189213 uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
190214 S += Imm;
......@@ -198,7 +222,7 @@ static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
198222// Update the immediate field in a AARCH64 ldr, str, and add instruction.
199223// Optionally limit the range of the written immediate by one or more bits
200224// (RangeLimit).
201static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
225void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
202226 uint32_t Orig = read32le(Off);
203227 Imm += (Orig >> 10) & 0xFFF;
204228 Orig &= ~(0xFFF << 10);
......@@ -221,7 +245,7 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
221245 if ((Orig & 0x4800000) == 0x4800000)
222246 Size += 4;
223247 if ((Imm & ((1 << Size) - 1)) != 0)
224 fatal("misaligned ldr/str offset");
248 error("misaligned ldr/str offset");
225249 applyArm64Imm(Off, Imm >> Size, Size);
226250}
227251
......@@ -250,21 +274,21 @@ static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off,
250274 applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
251275}
252276
253static void applyArm64Branch26(uint8_t *Off, int64_t V) {
277void applyArm64Branch26(uint8_t *Off, int64_t V) {
254278 if (!isInt<28>(V))
255 fatal("relocation out of range");
279 error("relocation out of range");
256280 or32(Off, (V & 0x0FFFFFFC) >> 2);
257281}
258282
259283static void applyArm64Branch19(uint8_t *Off, int64_t V) {
260284 if (!isInt<21>(V))
261 fatal("relocation out of range");
285 error("relocation out of range");
262286 or32(Off, (V & 0x001FFFFC) << 3);
263287}
264288
265289static void applyArm64Branch14(uint8_t *Off, int64_t V) {
266290 if (!isInt<16>(V))
267 fatal("relocation out of range");
291 error("relocation out of range");
268292 or32(Off, (V & 0x0000FFFC) << 3);
269293}
270294
......@@ -287,11 +311,37 @@ void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
287311 case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;
288312 case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;
289313 default:
290 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
314 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
291315 toString(File));
292316 }
293317}
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
295345void SectionChunk::writeTo(uint8_t *Buf) const {
296346 if (!hasData())
297347 return;
......@@ -302,46 +352,40 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
302352
303353 // Apply relocations.
304354 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
306358 // Check for an invalid relocation offset. This check isn't perfect, because
307359 // we don't have the relocation size, which is only known after checking the
308360 // machine and relocation type. As a result, a relocation may overwrite the
309361 // beginning of the following input section.
310 if (Rel.VirtualAddress >= InputSize)
311 fatal("relocation points beyond the end of its parent section");
362 if (Rel.VirtualAddress >= InputSize) {
363 error("relocation points beyond the end of its parent section");
364 continue;
365 }
312366
313367 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
315373 // Get the output section of the symbol for this relocation. The output
316374 // section is needed to compute SECREL and SECTION relocations used in debug
317375 // info.
318 auto *Sym =
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();
376 Chunk *C = Sym ? Sym->getChunk() : nullptr;
332377 OutputSection *OS = C ? C->getOutputSection() : nullptr;
333378
334 // Only absolute and __ImageBase symbols lack an output section. For any
335 // other symbol, this indicates that the chunk was discarded. Normally
336 // relocations against discarded sections are an error. However, debug info
337 // sections are not GC roots and can end up with these kinds of relocations.
338 // Skip these relocations.
339 if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
340 if (isCodeView() || isDWARF())
341 continue;
342 fatal("relocation against symbol in discarded section: " +
343 Sym->getName());
379 // Skip the relocation if it refers to a discarded section, and diagnose it
380 // as an error if appropriate. If a symbol was discarded early, it may be
381 // null. If it was discarded late, the output section will be null, unless
382 // it was an absolute or synthetic symbol.
383 if (!Sym ||
384 (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym))) {
385 maybeReportRelocationToDiscarded(this, Sym, Rel);
386 continue;
344387 }
388
345389 uint64_t S = Sym->getRVA();
346390
347391 // Compute the RVA of the relocation for relative relocations.
......@@ -399,17 +443,125 @@ static uint8_t getBaserelType(const coff_relocation &Rel) {
399443// fixed by the loader if load-time relocation is needed.
400444// Only called when base relocation is enabled.
401445void 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];
403448 uint8_t Ty = getBaserelType(Rel);
404449 if (Ty == IMAGE_REL_BASED_ABSOLUTE)
405450 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];
407454 if (!Target || isa<DefinedAbsolute>(Target))
408455 continue;
409456 Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
410457 }
411458}
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
413565bool SectionChunk::hasData() const {
414566 return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
415567}
......@@ -447,6 +599,13 @@ void SectionChunk::replace(SectionChunk *Other) {
447599 Other->Live = false;
448600}
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
450609CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
451610 // Common symbols are aligned on natural boundaries up to 32 bytes.
452611 // This is what MSVC link.exe does.
......@@ -460,6 +619,7 @@ uint32_t CommonChunk::getOutputCharacteristics() const {
460619
461620void StringChunk::writeTo(uint8_t *Buf) const {
462621 memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
622 Buf[OutputSectionOff + Str.size()] = '\0';
463623}
464624
465625ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
......@@ -502,13 +662,50 @@ void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
502662 applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
503663}
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
505704void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
506705 Res->emplace_back(getRVA());
507706}
508707
509size_t LocalImportChunk::getSize() const {
510 return Config->is64() ? 8 : 4;
511}
708size_t LocalImportChunk::getSize() const { return Config->Wordsize; }
512709
513710void LocalImportChunk::writeTo(uint8_t *Buf) const {
514711 if (Config->is64()) {
......@@ -528,6 +725,34 @@ void RVATableChunk::writeTo(uint8_t *Buf) const {
528725 "RVA tables should be de-duplicated");
529726}
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
531756// Windows-specific. This class represents a block in .reloc section.
532757// The format is described here.
533758//
......@@ -613,13 +838,16 @@ void MergeChunk::addSection(SectionChunk *C) {
613838}
614839
615840void MergeChunk::finalizeContents() {
616 for (SectionChunk *C : Sections)
617 if (C->isLive())
618 Builder.add(toStringRef(C->getContents()));
619 Builder.finalize();
841 if (!Finalized) {
842 for (SectionChunk *C : Sections)
843 if (C->Live)
844 Builder.add(toStringRef(C->getContents()));
845 Builder.finalize();
846 Finalized = true;
847 }
620848
621849 for (SectionChunk *C : Sections) {
622 if (!C->isLive())
850 if (!C->Live)
623851 continue;
624852 size_t Off = Builder.getOffset(toStringRef(C->getContents()));
625853 C->setOutputSection(Out);
......@@ -640,5 +868,16 @@ void MergeChunk::writeTo(uint8_t *Buf) const {
640868 Builder.write(Buf + OutputSectionOff);
641869}
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
643882} // namespace coff
644883} // namespace lld
deps/lld/COFF/Chunks.h+114-16
......@@ -36,6 +36,7 @@ class DefinedImportData;
3636class DefinedRegular;
3737class ObjFile;
3838class OutputSection;
39class RuntimePseudoReloc;
3940class Symbol;
4041
4142// Mask for permissions (discardable, writable, readable, executable, etc).
......@@ -63,6 +64,13 @@ public:
6364 // before calling this function.
6465 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
6674 // Called by the writer after an RVA is assigned, but before calling
6775 // getSize().
6876 virtual void finalizeContents() {}
......@@ -114,6 +122,10 @@ protected:
114122public:
115123 // The offset from beginning of the output section. The writer sets a value.
116124 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;
117129};
118130
119131// A chunk corresponding a section of an input file.
......@@ -140,6 +152,8 @@ public:
140152
141153 SectionChunk(ObjFile *File, const coff_section *Header);
142154 static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
155 void readRelocTargets() override;
156 void resetRelocTargets() override;
143157 size_t getSize() const override { return Header->SizeOfRawData; }
144158 ArrayRef<uint8_t> getContents() const;
145159 void writeTo(uint8_t *Buf) const override;
......@@ -157,6 +171,8 @@ public:
157171 void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
158172 uint64_t P) const;
159173
174 void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &Res);
175
160176 // Called if the garbage collector decides to not include this chunk
161177 // in a final output. It's supposed to print out a log message to stdout.
162178 void printDiscardedMessage() const;
......@@ -167,16 +183,6 @@ public:
167183
168184 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
180186 // True if this is a codeview debug info chunk. These will not be laid out in
181187 // the image. Instead they will end up in the PDB, if one is requested.
182188 bool isCodeView() const {
......@@ -197,10 +203,13 @@ public:
197203 // Allow iteration over the associated child chunks for this section.
198204 ArrayRef<SectionChunk *> children() const { return AssocChildren; }
199205
206 // The section ID this chunk belongs to in its Obj.
207 uint32_t getSectionNumber() const;
208
200209 // A pointer pointing to a replacement for this chunk.
201210 // Initially it points to "this" object. If this chunk is merged
202211 // 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.
204213 SectionChunk *Repl;
205214
206215 // The CRC of the contents as described in the COFF spec 4.5.5.
......@@ -217,13 +226,17 @@ public:
217226
218227 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
220236private:
221237 StringRef SectionName;
222238 std::vector<SectionChunk *> AssocChildren;
223239
224 // Used by the garbage collector.
225 bool Live;
226
227240 // Used for ICF (Identical COMDAT Folding)
228241 void replace(SectionChunk *Other);
229242 uint32_t Class[2] = {0, 0};
......@@ -254,6 +267,7 @@ public:
254267
255268private:
256269 llvm::StringTableBuilder Builder;
270 bool Finalized = false;
257271};
258272
259273// A chunk for common symbols. Common chunks don't have actual data.
......@@ -297,7 +311,7 @@ static const uint8_t ImportThunkARM64[] = {
297311};
298312
299313// Windows-specific.
300// A chunk for DLL import jump table entry. In a final output, it's
314// A chunk for DLL import jump table entry. In a final output, its
301315// contents will be a JMP instruction to some __imp_ symbol.
302316class ImportThunkChunkX64 : public Chunk {
303317public:
......@@ -341,11 +355,31 @@ private:
341355 Defined *ImpSymbol;
342356};
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
344376// Windows-specific.
345377// See comments for DefinedLocalImport class.
346378class LocalImportChunk : public Chunk {
347379public:
348 explicit LocalImportChunk(Defined *S) : Sym(S) {}
380 explicit LocalImportChunk(Defined *S) : Sym(S) {
381 Alignment = Config->Wordsize;
382 }
349383 size_t getSize() const override;
350384 void getBaserels(std::vector<Baserel> *Res) override;
351385 void writeTo(uint8_t *Buf) const override;
......@@ -414,9 +448,73 @@ public:
414448 uint8_t Type;
415449};
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
417511void applyMOV32T(uint8_t *Off, uint32_t V);
418512void 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
420518} // namespace coff
421519} // namespace lld
422520
deps/lld/COFF/Config.h+4-1
......@@ -84,6 +84,7 @@ struct Configuration {
8484 bool is64() { return Machine == AMD64 || Machine == ARM64; }
8585
8686 llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
87 size_t Wordsize;
8788 bool Verbose = false;
8889 WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
8990 Symbol *Entry = nullptr;
......@@ -94,7 +95,8 @@ struct Configuration {
9495 bool DoICF = true;
9596 bool TailMerge;
9697 bool Relocatable = true;
97 bool Force = false;
98 bool ForceMultiple = false;
99 bool ForceUnresolved = false;
98100 bool Debug = false;
99101 bool DebugDwarf = false;
100102 bool DebugGHashes = false;
......@@ -195,6 +197,7 @@ struct Configuration {
195197 bool MinGW = false;
196198 bool WarnMissingOrderSymbol = true;
197199 bool WarnLocallyDefinedImported = true;
200 bool WarnDebugInfoUnusable = true;
198201 bool Incremental = true;
199202 bool IntegrityCheck = false;
200203 bool KillAt = false;
deps/lld/COFF/DLL.cpp+83-35
......@@ -35,8 +35,6 @@ namespace {
3535
3636// Import table
3737
38static int ptrSize() { return Config->is64() ? 8 : 4; }
39
4038// A chunk for the import descriptor table.
4139class HintNameChunk : public Chunk {
4240public:
......@@ -49,6 +47,7 @@ public:
4947 }
5048
5149 void writeTo(uint8_t *Buf) const override {
50 memset(Buf + OutputSectionOff, 0, getSize());
5251 write16le(Buf + OutputSectionOff, Hint);
5352 memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
5453 }
......@@ -61,11 +60,14 @@ private:
6160// A chunk for the import descriptor table.
6261class LookupChunk : public Chunk {
6362public:
64 explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = ptrSize(); }
65 size_t getSize() const override { return ptrSize(); }
63 explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = Config->Wordsize; }
64 size_t getSize() const override { return Config->Wordsize; }
6665
6766 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());
6971 }
7072
7173 Chunk *HintName;
......@@ -76,8 +78,10 @@ public:
7678// See Microsoft PE/COFF spec 7.1. Import Header for details.
7779class OrdinalOnlyChunk : public Chunk {
7880public:
79 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { Alignment = ptrSize(); }
80 size_t getSize() const override { return ptrSize(); }
81 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
82 Alignment = Config->Wordsize;
83 }
84 size_t getSize() const override { return Config->Wordsize; }
8185
8286 void writeTo(uint8_t *Buf) const override {
8387 // An import-by-ordinal slot has MSB 1 to indicate that
......@@ -99,6 +103,8 @@ public:
99103 size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
100104
101105 void writeTo(uint8_t *Buf) const override {
106 memset(Buf + OutputSectionOff, 0, getSize());
107
102108 auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
103109 E->ImportLookupTableRVA = LookupTab->getRVA();
104110 E->NameRVA = DLLName->getRVA();
......@@ -118,6 +124,10 @@ public:
118124 bool hasData() const override { return false; }
119125 size_t getSize() const override { return Size; }
120126
127 void writeTo(uint8_t *Buf) const override {
128 memset(Buf + OutputSectionOff, 0, Size);
129 }
130
121131private:
122132 size_t Size;
123133};
......@@ -160,6 +170,8 @@ public:
160170 }
161171
162172 void writeTo(uint8_t *Buf) const override {
173 memset(Buf + OutputSectionOff, 0, getSize());
174
163175 auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
164176 E->Attributes = 1;
165177 E->Name = DLLName->getRVA();
......@@ -230,6 +242,36 @@ static const uint8_t ThunkARM[] = {
230242 0x60, 0x47, // bx ip
231243};
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
233275// A chunk for the delay import thunk.
234276class ThunkChunkX64 : public Chunk {
235277public:
......@@ -298,11 +340,35 @@ public:
298340 Defined *Helper = nullptr;
299341};
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
301365// A chunk for the import descriptor table.
302366class DelayAddressChunk : public Chunk {
303367public:
304 explicit DelayAddressChunk(Chunk *C) : Thunk(C) { Alignment = ptrSize(); }
305 size_t getSize() const override { return ptrSize(); }
368 explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
369 Alignment = Config->Wordsize;
370 }
371 size_t getSize() const override { return Config->Wordsize; }
306372
307373 void writeTo(uint8_t *Buf) const override {
308374 if (Config->is64()) {
......@@ -338,6 +404,8 @@ public:
338404 }
339405
340406 void writeTo(uint8_t *Buf) const override {
407 memset(Buf + OutputSectionOff, 0, getSize());
408
341409 auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
342410 E->NameRVA = DLLName->getRVA();
343411 E->OrdinalBase = 0;
......@@ -362,6 +430,8 @@ public:
362430 size_t getSize() const override { return Size * 4; }
363431
364432 void writeTo(uint8_t *Buf) const override {
433 memset(Buf + OutputSectionOff, 0, getSize());
434
365435 for (const Export &E : Config->Exports) {
366436 uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
367437 uint32_t Bit = 0;
......@@ -418,30 +488,6 @@ private:
418488
419489} // 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
445491void IdataContents::create() {
446492 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
447493
......@@ -465,8 +511,8 @@ void IdataContents::create() {
465511 Hints.push_back(C);
466512 }
467513 // Terminate with null values.
468 Lookups.push_back(make<NullChunk>(ptrSize()));
469 Addresses.push_back(make<NullChunk>(ptrSize()));
514 Lookups.push_back(make<NullChunk>(Config->Wordsize));
515 Addresses.push_back(make<NullChunk>(Config->Wordsize));
470516
471517 for (int I = 0, E = Syms.size(); I < E; ++I)
472518 Syms[I]->setLocation(Addresses[Base + I]);
......@@ -555,6 +601,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
555601 return make<ThunkChunkX86>(S, Dir, Helper);
556602 case ARMNT:
557603 return make<ThunkChunkARM>(S, Dir, Helper);
604 case ARM64:
605 return make<ThunkChunkARM64>(S, Dir, Helper);
558606 default:
559607 llvm_unreachable("unsupported machine type");
560608 }
deps/lld/COFF/DLL.h+1-8
......@@ -19,19 +19,12 @@ namespace coff {
1919// Windows-specific.
2020// IdataContents creates all chunks for the DLL import table.
2121// 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.
2323class IdataContents {
2424public:
2525 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
2626 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:
3528 void create();
3629
3730 std::vector<DefinedImportData *> Imports;
deps/lld/COFF/Driver.cpp+276-185
......@@ -32,6 +32,7 @@
3232#include "llvm/Option/ArgList.h"
3333#include "llvm/Option/Option.h"
3434#include "llvm/Support/Debug.h"
35#include "llvm/Support/LEB128.h"
3536#include "llvm/Support/Path.h"
3637#include "llvm/Support/Process.h"
3738#include "llvm/Support/TarWriter.h"
......@@ -56,7 +57,7 @@ Configuration *Config;
5657LinkerDriver *Driver;
5758
5859bool 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]);
6061 errorHandler().ErrorOS = &Diag;
6162 errorHandler().ColorDiagnostics = Diag.has_colors();
6263 errorHandler().ErrorLimitExceededMsg =
......@@ -370,13 +371,30 @@ Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
370371 return Path;
371372}
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
373386// Find library file from search path.
374387StringRef LinkerDriver::doFindLib(StringRef Filename) {
375388 // Add ".lib" to Filename if that has no file extension.
376389 bool HasExt = Filename.contains('.');
377390 if (!HasExt)
378391 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;
380398}
381399
382400// Resolves a library path. /nodefaultlib options are taken into
......@@ -429,29 +447,48 @@ StringRef LinkerDriver::findDefaultEntry() {
429447 assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
430448 "must handle /subsystem before calling this");
431449
432 // As a special case, if /nodefaultlib is given, we directly look for an
433 // entry point. This is because, if no default library is linked, users
434 // need to define an entry point instead of a "main".
435 bool FindMain = !Config->NoDefaultLibAll;
450 if (Config->MinGW)
451 return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
452 ? "WinMainCRTStartup"
453 : "mainCRTStartup");
454
436455 if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
437 if (findUnderscoreMangle(FindMain ? "WinMain" : "WinMainCRTStartup"))
438 return mangle("WinMainCRTStartup");
439 if (findUnderscoreMangle(FindMain ? "wWinMain" : "wWinMainCRTStartup"))
440 return mangle("wWinMainCRTStartup");
441 }
442 if (findUnderscoreMangle(FindMain ? "main" : "mainCRTStartup"))
443 return mangle("mainCRTStartup");
444 if (findUnderscoreMangle(FindMain ? "wmain" : "wmainCRTStartup"))
445 return mangle("wmainCRTStartup");
446 return "";
456 if (findUnderscoreMangle("wWinMain")) {
457 if (!findUnderscoreMangle("WinMain"))
458 return mangle("wWinMainCRTStartup");
459 warn("found both wWinMain and WinMain; using latter");
460 }
461 return mangle("WinMainCRTStartup");
462 }
463 if (findUnderscoreMangle("wmain")) {
464 if (!findUnderscoreMangle("main"))
465 return mangle("wmainCRTStartup");
466 warn("found both wmain and main; using latter");
467 }
468 return mangle("mainCRTStartup");
447469}
448470
449471WindowsSubsystem LinkerDriver::inferSubsystem() {
450472 if (Config->DLL)
451473 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 }
453489 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
454 if (findUnderscoreMangle("WinMain") || findUnderscoreMangle("wWinMain"))
490 }
491 if (HaveWinMain || HaveWWinMain)
455492 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
456493 return IMAGE_SUBSYSTEM_UNKNOWN;
457494}
......@@ -497,26 +534,65 @@ static std::string createResponseFile(const opt::InputArgList &Args,
497534 return Data.str();
498535}
499536
500static unsigned getDefaultDebugType(const opt::InputArgList &Args) {
501 unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);
537enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab };
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);
502591 if (Args.hasArg(OPT_driver))
503592 DebugTypes |= static_cast<unsigned>(DebugType::PData);
504593 if (Args.hasArg(OPT_profile))
505594 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);
520596 return DebugTypes;
521597}
522598
......@@ -676,131 +752,6 @@ static void parseModuleDefs(StringRef Path) {
676752 }
677753}
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
804755void LinkerDriver::enqueueTask(std::function<void()> Task) {
805756 TaskQueue.push_back(std::move(Task));
806757}
......@@ -856,6 +807,97 @@ static void parseOrderFile(StringRef Arg) {
856807 }
857808}
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
859901void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
860902 // If the first command line argument is "/lib", link.exe acts like lib.exe.
861903 // We call our own implementation of lib.exe that understands bitcode files.
......@@ -944,11 +986,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
944986
945987 // Handle /ignore
946988 for (auto *Arg : Args.filtered(OPT_ignore)) {
947 if (StringRef(Arg->getValue()) == "4037")
948 Config->WarnMissingOrderSymbol = false;
949 else if (StringRef(Arg->getValue()) == "4217")
950 Config->WarnLocallyDefinedImported = false;
951 // Other warning numbers are ignored.
989 SmallVector<StringRef, 8> Vec;
990 StringRef(Arg->getValue()).split(Vec, ',');
991 for (StringRef S : Vec) {
992 if (S == "4037")
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 }
9521000 }
9531001
9541002 // Handle /out
......@@ -962,20 +1010,26 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
9621010
9631011 // Handle /force or /force:unresolved
9641012 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
9671019 // 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) {
9691023 Config->Debug = true;
9701024 Config->Incremental = true;
971 if (auto *Arg = Args.getLastArg(OPT_debugtype))
972 Config->DebugTypes = parseDebugType(Arg->getValue());
973 else
974 Config->DebugTypes = getDefaultDebugType(Args);
9751025 }
9761026
1027 // Handle /debugtype
1028 Config->DebugTypes = parseDebugTypes(Args);
1029
9771030 // Handle /pdb
978 bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash);
1031 bool ShouldCreatePDB =
1032 (Debug == DebugKind::Full || Debug == DebugKind::GHash);
9791033 if (ShouldCreatePDB) {
9801034 if (auto *Arg = Args.getLastArg(OPT_pdb))
9811035 Config->PDBPath = Arg->getValue();
......@@ -1096,7 +1150,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
10961150 Config->Implib = Arg->getValue();
10971151
10981152 // Handle /opt.
1099 bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile);
1153 bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile);
11001154 unsigned ICFLevel =
11011155 Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
11021156 unsigned TailMerge = 1;
......@@ -1181,6 +1235,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
11811235 parseMerge(".xdata=.rdata");
11821236 parseMerge(".bss=.data");
11831237
1238 if (Config->MinGW) {
1239 parseMerge(".ctors=.rdata");
1240 parseMerge(".dtors=.rdata");
1241 parseMerge(".CRT=.rdata");
1242 }
1243
11841244 // Handle /section
11851245 for (auto *Arg : Args.filtered(OPT_section))
11861246 parseSection(Arg->getValue());
......@@ -1234,9 +1294,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
12341294 Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
12351295 Config->TerminalServerAware =
12361296 !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
1237 Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf);
1238 Config->DebugGHashes = Args.hasArg(OPT_debug_ghash);
1239 Config->DebugSymtab = Args.hasArg(OPT_debug_symtab);
1297 Config->DebugDwarf = Debug == DebugKind::Dwarf;
1298 Config->DebugGHashes = Debug == DebugKind::GHash;
1299 Config->DebugSymtab = Debug == DebugKind::Symtab;
12401300
12411301 Config->MapFile = getMapFile(Args);
12421302
......@@ -1266,10 +1326,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
12661326 return;
12671327
12681328 std::set<sys::fs::UniqueID> WholeArchives;
1269 for (auto *Arg : Args.filtered(OPT_wholearchive_file))
1270 if (Optional<StringRef> Path = doFindFile(Arg->getValue()))
1329 AutoExporter Exporter;
1330 for (auto *Arg : Args.filtered(OPT_wholearchive_file)) {
1331 if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
12711332 if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))
12721333 WholeArchives.insert(*ID);
1334 Exporter.addWholeArchive(*Path);
1335 }
1336 }
12731337
12741338 // A predicate returning true if a given path is an argument for
12751339 // /wholearchive:, or /wholearchive is enabled globally.
......@@ -1300,12 +1364,16 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
13001364 // Read all input files given via the command line.
13011365 run();
13021366
1367 if (errorCount())
1368 return;
1369
13031370 // We should have inferred a machine type by now from the input files, but if
13041371 // not we assume x64.
13051372 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
13061373 warn("/machine is not specified. x64 is assumed");
13071374 Config->Machine = AMD64;
13081375 }
1376 Config->Wordsize = Config->is64() ? 8 : 4;
13091377
13101378 // Input files can be Windows resource files (.res files). We use
13111379 // WindowsResource to convert resource files to a regular COFF file,
......@@ -1418,6 +1486,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
14181486 // tools won't work correctly if these assumptions are not held.
14191487 sys::fs::make_absolute(Config->PDBAltPath);
14201488 sys::path::remove_dots(Config->PDBAltPath);
1489 } else {
1490 // Don't do this earlier, so that Config->OutputFile is ready.
1491 parsePDBAltPath(Config->PDBAltPath);
14211492 }
14221493 }
14231494
......@@ -1441,6 +1512,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
14411512 // Needed for MSVC 2017 15.5 CRT.
14421513 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
14441522 // This code may add new undefined symbols to the link, which may enqueue more
14451523 // symbol resolution tasks, so we need to continue executing tasks until we
14461524 // converge.
......@@ -1480,18 +1558,29 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
14801558 if (errorCount())
14811559 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
14901561 // Do LTO by compiling bitcode input files to a set of native COFF files then
14911562 // link those files.
14921563 Symtab->addCombinedLTOObjects();
14931564 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
14951584 // Make sure we have resolved all symbols.
14961585 Symtab->reportRemainingUndefines();
14971586 if (errorCount())
......@@ -1510,7 +1599,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15101599 // are chosen to be exported.
15111600 if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
15121601 Args.hasArg(OPT_export_all_symbols))) {
1513 AutoExporter Exporter;
1602 Exporter.initSymbolExcludes();
15141603
15151604 Symtab->forEachSymbol([=](Symbol *S) {
15161605 auto *Def = dyn_cast<Defined>(S);
......@@ -1574,8 +1663,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15741663 markLive(Symtab->getChunks());
15751664
15761665 // Identify identical COMDAT sections to merge them.
1577 if (Config->DoICF)
1666 if (Config->DoICF) {
1667 findKeepUniqueSections();
15781668 doICF(Symtab->getChunks());
1669 }
15791670
15801671 // Write the result.
15811672 writeResult();
deps/lld/COFF/Driver.h+1-2
......@@ -89,6 +89,7 @@ private:
8989 Optional<StringRef> findLib(StringRef Filename);
9090 StringRef doFindFile(StringRef Filename);
9191 StringRef doFindLib(StringRef Filename);
92 StringRef doFindLibMinGW(StringRef Filename);
9293
9394 // Parses LIB environment which contains a list of search paths.
9495 void addLibSearchPaths();
......@@ -114,8 +115,6 @@ private:
114115 StringRef findDefaultEntry();
115116 WindowsSubsystem inferSubsystem();
116117
117 void invokeMSVC(llvm::opt::InputArgList &Args);
118
119118 void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);
120119 void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
121120 StringRef ParentName);
deps/lld/COFF/DriverUtils.cpp+3-21
......@@ -713,26 +713,6 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {
713713 return MBRef;
714714}
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
736716// Create OptTable
737717
738718// Create prefix string literals used in Options.td
......@@ -883,7 +863,9 @@ std::vector<const char *> ArgParser::tokenize(StringRef S) {
883863}
884864
885865void 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);
887869}
888870
889871} // namespace coff
deps/lld/COFF/ICF.cpp+24-7
......@@ -22,6 +22,7 @@
2222#include "Chunks.h"
2323#include "Symbols.h"
2424#include "lld/Common/ErrorHandler.h"
25#include "lld/Common/Threads.h"
2526#include "lld/Common/Timer.h"
2627#include "llvm/ADT/Hashing.h"
2728#include "llvm/Support/Debug.h"
......@@ -80,7 +81,7 @@ private:
8081bool ICF::isEligible(SectionChunk *C) {
8182 // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
8283 bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
83 if (!C->isCOMDAT() || !C->isLive() || Writable)
84 if (!C->isCOMDAT() || !C->Live || Writable)
8485 return false;
8586
8687 // Code sections are eligible.
......@@ -93,7 +94,11 @@ bool ICF::isEligible(SectionChunk *C) {
9394 return true;
9495
9596 // 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;
97102}
98103
99104// Split an equivalence class into smaller classes.
......@@ -222,10 +227,10 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
222227 size_t Boundaries[NumShards + 1];
223228 Boundaries[0] = 0;
224229 Boundaries[NumShards] = Chunks.size();
225 for_each_n(parallel::par, size_t(1), NumShards, [&](size_t I) {
230 parallelForEachN(1, NumShards, [&](size_t I) {
226231 Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size());
227232 });
228 for_each_n(parallel::par, size_t(1), NumShards + 1, [&](size_t I) {
233 parallelForEachN(1, NumShards + 1, [&](size_t I) {
229234 if (Boundaries[I - 1] < Boundaries[I]) {
230235 forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
231236 }
......@@ -257,11 +262,23 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
257262 SC->Class[0] = NextId++;
258263
259264 // Initially, we use hash values to partition sections.
260 for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) {
261 // Set MSB to 1 to avoid collisions with non-hash classs.
262 SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31);
265 parallelForEach(Chunks, [&](SectionChunk *SC) {
266 SC->Class[0] = xxHash64(SC->getContents());
263267 });
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
265282 // From now on, sections in Chunks are ordered so that sections in
266283 // the same group are consecutive in the vector.
267284 std::stable_sort(Chunks.begin(), Chunks.end(),
deps/lld/COFF/InputFiles.cpp+35-8
......@@ -54,8 +54,16 @@ std::vector<BitcodeFile *> BitcodeFile::Instances;
5454static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
5555 Symbol *Source, Symbol *Target) {
5656 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;
5865 Symtab->reportDuplicate(Source, F);
66 }
5967 U->WeakAlias = Target;
6068 }
6169}
......@@ -147,9 +155,10 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
147155 const coff_aux_section_definition *Def,
148156 StringRef LeaderName) {
149157 const coff_section *Sec;
150 StringRef Name;
151158 if (auto EC = COFFObj->getSection(SectionNumber, Sec))
152159 fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());
160
161 StringRef Name;
153162 if (auto EC = COFFObj->getSectionName(Sec, Name))
154163 fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +
155164 EC.message());
......@@ -161,6 +170,11 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
161170 return nullptr;
162171 }
163172
173 if (Name == ".llvm_addrsig") {
174 AddrsigSec = Sec;
175 return nullptr;
176 }
177
164178 // Object files may have DWARF debug info or MS CodeView debug info
165179 // (or both).
166180 //
......@@ -168,8 +182,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
168182 // of the linker; they are just a data section containing relocations.
169183 // We can just link them to complete debug info.
170184 //
171 // CodeView needs a linker support. We need to interpret and debug
172 // info, and then write it to a separate .pdb file.
185 // CodeView needs linker support. We need to interpret debug info,
186 // and then write it to a separate .pdb file.
173187
174188 // Ignore DWARF debug info unless /debug is given.
175189 if (!Config->Debug && Name.startswith(".debug_"))
......@@ -267,10 +281,17 @@ Symbol *ObjFile::createRegular(COFFSymbolRef Sym) {
267281 COFFObj->getSymbolName(Sym, Name);
268282 if (SC)
269283 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;
270291 return Symtab->addUndefined(Name, this, false);
271292 }
272293 if (SC)
273 return make<DefinedRegular>(this, /*Name*/ "", false,
294 return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
274295 /*IsExternal*/ false, Sym.getGeneric(), SC);
275296 return nullptr;
276297}
......@@ -318,7 +339,7 @@ void ObjFile::initializeSymbols() {
318339
319340 for (uint32_t I : PendingIndexes) {
320341 COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
321 if (auto *Def = Sym.getSectionDefinition()) {
342 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
322343 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
323344 readAssociativeDefinition(Sym, Def);
324345 else if (Config->MinGW)
......@@ -401,7 +422,7 @@ Optional<Symbol *> ObjFile::createDefined(
401422 std::tie(Leader, Prevailing) =
402423 Symtab->addComdat(this, GetName(), Sym.getGeneric());
403424 } else {
404 Leader = make<DefinedRegular>(this, /*Name*/ "", false,
425 Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
405426 /*IsExternal*/ false, Sym.getGeneric());
406427 Prevailing = true;
407428 }
......@@ -421,7 +442,7 @@ Optional<Symbol *> ObjFile::createDefined(
421442 // leader symbol by setting the section's ComdatDefs pointer if we encounter a
422443 // non-associative comdat.
423444 if (SparseChunks[SectionNumber] == PendingComdat) {
424 if (auto *Def = Sym.getSectionDefinition()) {
445 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
425446 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
426447 readAssociativeDefinition(Sym, Def);
427448 else
......@@ -429,8 +450,10 @@ Optional<Symbol *> ObjFile::createDefined(
429450 }
430451 }
431452
453 // readAssociativeDefinition() writes to SparseChunks, so need to check again.
432454 if (SparseChunks[SectionNumber] == PendingComdat)
433455 return None;
456
434457 return createRegular(Sym);
435458}
436459
......@@ -481,6 +504,10 @@ void ImportFile::parse() {
481504 ExternalName = ExtName;
482505
483506 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
485512 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
486513 static_cast<void>(Symtab->addImportData(Name, this));
deps/lld/COFF/InputFiles.h+12-1
......@@ -15,6 +15,7 @@
1515#include "llvm/ADT/ArrayRef.h"
1616#include "llvm/ADT/DenseMap.h"
1717#include "llvm/ADT/DenseSet.h"
18#include "llvm/DebugInfo/CodeView/TypeRecord.h"
1819#include "llvm/LTO/LTO.h"
1920#include "llvm/Object/Archive.h"
2021#include "llvm/Object/COFF.h"
......@@ -122,9 +123,12 @@ public:
122123 return Symbols[SymbolIndex];
123124 }
124125
125 // Returns the underying COFF file.
126 // Returns the underlying COFF file.
126127 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
128132 static std::vector<ObjFile *> Instances;
129133
130134 // Flags in the absolute @feat.00 symbol if it is present. These usually
......@@ -145,6 +149,13 @@ public:
145149 // if we are not producing a PDB.
146150 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
148159private:
149160 void initializeChunks();
150161 void initializeSymbols();
deps/lld/COFF/LTO.cpp+3
......@@ -60,6 +60,9 @@ static std::unique_ptr<lto::LTO> createLTO() {
6060 C.DisableVerify = true;
6161 C.DiagHandler = diagnosticHandler;
6262 C.OptLevel = Config->LTOO;
63 C.CPU = GetCPUStr();
64 C.MAttrs = GetMAttrs();
65
6366 if (Config->SaveTemps)
6467 checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
6568 /*UseInputModulePath*/ true));
deps/lld/COFF/MapFile.cpp+1-1
......@@ -110,7 +110,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
110110 writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
111111 OS << Sec->Name << '\n';
112112
113 for (Chunk *C : Sec->getChunks()) {
113 for (Chunk *C : Sec->Chunks) {
114114 auto *SC = dyn_cast<SectionChunk>(C);
115115 if (!SC)
116116 continue;
deps/lld/COFF/MarkLive.cpp+4-4
......@@ -32,13 +32,13 @@ void markLive(ArrayRef<Chunk *> Chunks) {
3232 // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
3333 for (Chunk *C : Chunks)
3434 if (auto *SC = dyn_cast<SectionChunk>(C))
35 if (SC->isLive())
35 if (SC->Live)
3636 Worklist.push_back(SC);
3737
3838 auto Enqueue = [&](SectionChunk *C) {
39 if (C->isLive())
39 if (C->Live)
4040 return;
41 C->markLive();
41 C->Live = true;
4242 Worklist.push_back(C);
4343 };
4444
......@@ -57,7 +57,7 @@ void markLive(ArrayRef<Chunk *> Chunks) {
5757
5858 while (!Worklist.empty()) {
5959 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
6262 // Mark all symbols listed in the relocation table for this section.
6363 for (Symbol *B : SC->symbols())
deps/lld/COFF/MinGW.cpp+36-6
......@@ -19,7 +19,23 @@ using namespace lld::coff;
1919using namespace llvm;
2020using 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 };
2339 if (Config->Machine == I386) {
2440 ExcludeSymbols = {
2541 "__NULL_IMPORT_DESCRIPTOR",
......@@ -36,9 +52,10 @@ AutoExporter::AutoExporter() {
3652 "_DllEntryPoint@12",
3753 "_DllMainCRTStartup@12",
3854 };
55 ExcludeSymbolPrefixes.insert("__head_");
3956 } else {
4057 ExcludeSymbols = {
41 "_NULL_IMPORT_DESCRIPTOR",
58 "__NULL_IMPORT_DESCRIPTOR",
4259 "_pei386_runtime_relocator",
4360 "do_pseudo_reloc",
4461 "impure_ptr",
......@@ -52,8 +69,11 @@ AutoExporter::AutoExporter() {
5269 "DllEntryPoint",
5370 "DllMainCRTStartup",
5471 };
72 ExcludeSymbolPrefixes.insert("_head_");
5573 }
74}
5675
76AutoExporter::AutoExporter() {
5777 ExcludeLibs = {
5878 "libgcc",
5979 "libgcc_s",
......@@ -64,6 +84,7 @@ AutoExporter::AutoExporter() {
6484 "libsupc++",
6585 "libobjc",
6686 "libgcj",
87 "libclang_rt.builtins",
6788 "libclang_rt.builtins-aarch64",
6889 "libclang_rt.builtins-arm",
6990 "libclang_rt.builtins-i386",
......@@ -90,6 +111,13 @@ AutoExporter::AutoExporter() {
90111 };
91112}
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
93121bool AutoExporter::shouldExport(Defined *Sym) const {
94122 if (!Sym || !Sym->isLive() || !Sym->getChunk())
95123 return false;
......@@ -101,10 +129,12 @@ bool AutoExporter::shouldExport(Defined *Sym) const {
101129 if (ExcludeSymbols.count(Sym->getName()))
102130 return false;
103131
104 // Don't export anything that looks like an import symbol (which also can be
105 // a manually defined data symbol with such a name).
106 if (Sym->getName().startswith("__imp_"))
107 return false;
132 for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
133 if (Sym->getName().startswith(Prefix))
134 return false;
135 for (StringRef Suffix : ExcludeSymbolSuffixes.keys())
136 if (Sym->getName().endswith(Suffix))
137 return false;
108138
109139 // If a corresponding __imp_ symbol exists and is defined, don't export it.
110140 if (Symtab->find(("__imp_" + Sym->getName()).str()))
deps/lld/COFF/MinGW.h+6
......@@ -23,7 +23,13 @@ class AutoExporter {
2323public:
2424 AutoExporter();
2525
26 void initSymbolExcludes();
27
28 void addWholeArchive(StringRef Path);
29
2630 llvm::StringSet<> ExcludeSymbols;
31 llvm::StringSet<> ExcludeSymbolPrefixes;
32 llvm::StringSet<> ExcludeSymbolSuffixes;
2733 llvm::StringSet<> ExcludeLibs;
2834 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
6666
6767def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
6868
69def manifest : F<"manifest">;
70def manifest_colon : P<"manifest", "Create manifest file">;
69def manifest : F<"manifest">, HelpText<"Create .manifest file">;
70def manifest_colon : P<
71 "manifest",
72 "NO disables manifest output; EMBED[,ID=#] embeds manifest as resource in the image">;
7173def manifestuac : P<"manifestuac", "User access control">;
72def manifestfile : P<"manifestfile", "Manifest file path">;
73def manifestdependency : P<"manifestdependency",
74 "Attributes for <dependency> in manifest file">;
75def manifestinput : P<"manifestinput", "Specify manifest file">;
74def manifestfile : P<"manifestfile", "Manifest output path, with /manifest">;
75def manifestdependency : P<
76 "manifestdependency",
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
7782// We cannot use multiclass P because class name "incl" is different
7883// from its command line option name. We do this because "include" is
......@@ -85,22 +90,28 @@ def deffile : Joined<["/", "-"], "def:">,
8590 HelpText<"Use module-definition file">;
8691
8792def 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">;
8994def debugtype : P<"debugtype", "Debug Info Options">;
9095def dll : F<"dll">, HelpText<"Create a DLL">;
9196def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
92def nodefaultlib_all : F<"nodefaultlib">;
93def noentry : F<"noentry">;
97def nodefaultlib_all : F<"nodefaultlib">,
98 HelpText<"Remove all default libraries">;
99def noentry : F<"noentry">,
100 HelpText<"Don't add reference to DllMainCRTStartup; only valid with /dll">;
94101def 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">;
96104def swaprun_cd : F<"swaprun:cd">;
97105def swaprun_net : F<"swaprun:net">;
98106def verbose : F<"verbose">;
99107def wholearchive_flag : F<"wholearchive">;
100108
101109def force : F<"force">,
110 HelpText<"Allow undefined and multiply defined symbols when creating executables">;
111def force_unresolved : F<"force:unresolved">,
102112 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">;
104115defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
105116
106117defm allowbind : B<"allowbind", "Enable DLL binding (default)",
......@@ -139,13 +150,9 @@ def help : F<"help">;
139150def help_q : Flag<["/?", "-?"], "">, Alias<help>;
140151
141152// LLD extensions
142def debug_ghash : F<"debug:ghash">;
143def debug_dwarf : F<"debug:dwarf">;
144def debug_symtab : F<"debug:symtab">;
145153def export_all_symbols : F<"export-all-symbols">;
146154def kill_at : F<"kill-at">;
147155def lldmingw : F<"lldmingw">;
148def msvclto : F<"msvclto">;
149156def output_def : Joined<["/", "-"], "output-def:">;
150157def pdb_source_path : P<"pdbsourcepath",
151158 "Base path used to make relative source file path absolute in PDB">;
deps/lld/COFF/PDB.cpp+720-283
......@@ -16,12 +16,14 @@
1616#include "Writer.h"
1717#include "lld/Common/ErrorHandler.h"
1818#include "lld/Common/Timer.h"
19#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
1920#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
2021#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
2122#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
2223#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
2324#include "llvm/DebugInfo/CodeView/RecordName.h"
2425#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
26#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
2527#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
2628#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
2729#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
......@@ -48,8 +50,10 @@
4850#include "llvm/Object/CVDebugRecord.h"
4951#include "llvm/Support/BinaryByteStream.h"
5052#include "llvm/Support/Endian.h"
53#include "llvm/Support/Errc.h"
5154#include "llvm/Support/FormatVariadic.h"
5255#include "llvm/Support/JamCRC.h"
56#include "llvm/Support/Parallel.h"
5357#include "llvm/Support/Path.h"
5458#include "llvm/Support/ScopedPrinter.h"
5559#include <memory>
......@@ -79,9 +83,14 @@ struct CVIndexMap {
7983 SmallVector<TypeIndex, 0> TPIMap;
8084 SmallVector<TypeIndex, 0> IPIMap;
8185 bool IsTypeServerMap = false;
86 bool IsPrecompiledTypeMap = false;
8287};
8388
89class DebugSHandler;
90
8491class PDBLinker {
92 friend DebugSHandler;
93
8594public:
8695 PDBLinker(SymbolTable *Symtab)
8796 : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
......@@ -93,7 +102,7 @@ public:
93102 }
94103
95104 /// 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
98107 /// Add natvis files specified on the command line.
99108 void addNatvisFiles();
......@@ -101,8 +110,10 @@ public:
101110 /// Link CodeView from each object file in the symbol table into the PDB.
102111 void addObjectsToPDB();
103112
104 /// Link CodeView from a single object file into the PDB.
105 void addObjFile(ObjFile *File);
113 /// Link CodeView from a single object file into the target (output) PDB.
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
107118 /// Produce a mapping from the type and item indices used in the object
108119 /// file to those in the destination PDB.
......@@ -115,18 +126,60 @@ public:
115126 /// If the object does not use a type server PDB (compiled with /Z7), we merge
116127 /// all the type and item records from the .debug$S stream and fill in the
117128 /// caller-provided ObjectIndexMap.
118 Expected<const CVIndexMap&> mergeDebugT(ObjFile *File,
119 CVIndexMap &ObjectIndexMap);
129 Expected<const CVIndexMap &> mergeDebugT(ObjFile *File,
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,
122 TypeServer2Record &TS);
159 void mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
160 std::vector<ulittle32_t *> &StringTableRefs,
161 BinaryStreamRef SymData);
123162
124163 /// Add the section map and section contributions to the PDB.
125164 void addSections(ArrayRef<OutputSection *> OutputSections,
126165 ArrayRef<uint8_t> SectionTable);
127166
128 /// Write the PDB to disk.
129 void commit();
167 /// Get the type table or the global type table if /DEBUG:GHASH is enabled.
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
131184private:
132185 BumpPtrAllocator Alloc;
......@@ -161,14 +214,101 @@ private:
161214 std::vector<pdb::SecMapEntry> SectionMap;
162215
163216 /// 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
166223 /// List of TypeServer PDBs which cannot be loaded.
167224 /// 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();
169270};
170271}
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
172312static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,
173313 StringRef Name) {
174314 for (SectionChunk *C : Sections)
......@@ -242,27 +382,79 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
242382 });
243383}
244384
245static Optional<TypeServer2Record>
246maybeReadTypeServerRecord(CVTypeArray &Types) {
247 auto I = Types.begin();
248 if (I == Types.end())
249 return None;
250 const CVType &Type = *I;
251 if (Type.kind() != LF_TYPESERVER2)
252 return None;
253 TypeServer2Record TS;
254 if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))
255 fatal("error reading type server record: " + toString(std::move(EC)));
256 return std::move(TS);
385// OBJs usually start their symbol stream with a S_OBJNAME record. This record
386// also contains the signature/key of the current PCH session. The signature
387// must be same for all objects which depend on the precompiled object.
388// Recompiling the precompiled headers will generate a new PCH key and thus
389// invalidate all the dependent objects.
390static uint32_t extractPCHSignature(ObjFile *File) {
391 auto DbgIt = find_if(File->getDebugChunks(), [](SectionChunk *C) {
392 return C->getSectionName() == ".debug$S";
393 });
394 if (!DbgIt)
395 return 0;
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;
257417}
258418
259Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
260 CVIndexMap &ObjectIndexMap) {
419Expected<const CVIndexMap &>
420PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) {
261421 ScopedTimer T(TypeMergingTimer);
262422
423 bool IsPrecompiledHeader = false;
424
263425 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 }
264432 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
267459 BinaryByteStream Stream(Data, support::little);
268460 CVTypeArray Types;
......@@ -270,13 +462,32 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
270462 if (auto EC = Reader.readArray(Types, Reader.getLength()))
271463 fatal("Reader::readArray failed: " + toString(std::move(EC)));
272464
273 // Look through type servers. If we've already seen this type server, don't
274 // merge any type information.
275 if (Optional<TypeServer2Record> TS = maybeReadTypeServerRecord(Types))
276 return maybeMergeTypeServerPDB(File, *TS);
465 auto FirstType = Types.begin();
466 if (FirstType == Types.end())
467 return *ObjectIndexMap;
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-provided
279 // ObjectIndexMap.
490 // Fill in the temporary, caller-provided ObjectIndexMap.
280491 if (Config->DebugGHashes) {
281492 ArrayRef<GloballyHashedType> Hashes;
282493 std::vector<GloballyHashedType> OwnedHashes;
......@@ -288,20 +499,28 @@ Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
288499 }
289500
290501 if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
291 ObjectIndexMap.TPIMap, Types, Hashes))
502 ObjectIndexMap->TPIMap, Types, Hashes,
503 File->PCHSignature))
292504 fatal("codeview::mergeTypeAndIdRecords failed: " +
293505 toString(std::move(Err)));
294506 } else {
295 if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
296 ObjectIndexMap.TPIMap, Types))
507 if (auto Err =
508 mergeTypeAndIdRecords(IDTable, TypeTable, ObjectIndexMap->TPIMap,
509 Types, File->PCHSignature))
297510 fatal("codeview::mergeTypeAndIdRecords failed: " +
298511 toString(std::move(Err)));
299512 }
300 return ObjectIndexMap;
513 return *ObjectIndexMap;
301514}
302515
303516static 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
305524 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(
306525 TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
307526 if (!MBOrErr)
......@@ -326,21 +545,27 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
326545 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
327546 // must match the GUID specified in the TypeServer2 record.
328547 if (ExpectedInfo->getGuid() != GuidFromObj)
329 return make_error<pdb::GenericError>(
330 pdb::generic_error_code::type_server_not_found, TSPath);
548 return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
331549
332550 return std::move(NS);
333551}
334552
335Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
336 TypeServer2Record &TS) {
337 const GUID& TSId = TS.getGuid();
553Expected<const CVIndexMap &>
554PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, const CVType &FirstType) {
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();
338561 StringRef TSPath = TS.getName();
339562
340563 // First, check if the PDB has previously failed to load.
341 if (MissingTypeServerPDBs.count(TSId))
342 return make_error<pdb::GenericError>(
343 pdb::generic_error_code::type_server_not_found, TSPath);
564 auto PrevErr = MissingTypeServerPDBs.find(TSId);
565 if (PrevErr != MissingTypeServerPDBs.end())
566 return createFileError(
567 TSPath,
568 make_error<StringError>(PrevErr->second, inconvertibleErrorCode()));
344569
345570 // Second, check if we already loaded a PDB with this GUID. Return the type
346571 // index mapping if we have it.
......@@ -355,20 +580,39 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
355580 // Check for a PDB at:
356581 // 1. The given file path
357582 // 2. Next to the object file or archive file
358 auto ExpectedSession = tryToLoadPDB(TSId, TSPath);
359 if (!ExpectedSession) {
360 consumeError(ExpectedSession.takeError());
361 StringRef LocalPath =
362 !File->ParentName.empty() ? File->ParentName : File->getName();
363 SmallString<128> Path = sys::path::parent_path(LocalPath);
364 sys::path::append(
365 Path, sys::path::filename(TSPath, sys::path::Style::windows));
366 ExpectedSession = tryToLoadPDB(TSId, Path);
367 }
583 auto ExpectedSession = handleExpected(
584 tryToLoadPDB(TSId, TSPath),
585 [&]() {
586 StringRef LocalPath =
587 !File->ParentName.empty() ? File->ParentName : File->getName();
588 SmallString<128> Path = sys::path::parent_path(LocalPath);
589 // Currently, type server PDBs are only created by cl, which only runs
590 // on Windows, so we can assume type server paths are Windows style.
591 sys::path::append(
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
368605 if (auto E = ExpectedSession.takeError()) {
369606 TypeServerIndexMappings.erase(TSId);
370 MissingTypeServerPDBs.emplace(TSId);
371 return std::move(E);
607
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));
372616 }
373617
374618 pdb::NativeSession *Session = ExpectedSession->get();
......@@ -394,9 +638,10 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
394638 auto IpiHashes =
395639 GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
396640
641 Optional<uint32_t> EndPrecomp;
397642 // Merge TPI first, because the IPI stream will reference type indices.
398643 if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
399 ExpectedTpi->typeArray(), TpiHashes))
644 ExpectedTpi->typeArray(), TpiHashes, EndPrecomp))
400645 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
401646
402647 // Merge IPI.
......@@ -419,6 +664,103 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
419664 return IndexMap;
420665}
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
422764static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
423765 if (TI.isSimple())
424766 return true;
......@@ -429,9 +771,11 @@ static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
429771}
430772
431773static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind,
432 MutableArrayRef<uint8_t> Contents,
774 MutableArrayRef<uint8_t> RecordBytes,
433775 const CVIndexMap &IndexMap,
434776 ArrayRef<TiReference> TypeRefs) {
777 MutableArrayRef<uint8_t> Contents =
778 RecordBytes.drop_front(sizeof(RecordPrefix));
435779 for (const TiReference &Ref : TypeRefs) {
436780 unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
437781 if (Contents.size() < Ref.Offset + ByteSize)
......@@ -477,7 +821,7 @@ recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents,
477821 switch (Kind) {
478822 case SymbolKind::S_FILESTATIC:
479823 // FileStaticSym::ModFileOffset
480 recordStringTableReferenceAtOffset(Contents, 4, StrTableRefs);
824 recordStringTableReferenceAtOffset(Contents, 8, StrTableRefs);
481825 break;
482826 case SymbolKind::S_DEFRANGE:
483827 case SymbolKind::S_DEFRANGE_SUBFIELD:
......@@ -542,58 +886,26 @@ static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData,
542886
543887/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
544888/// The object file may not be aligned.
545static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym,
546 BumpPtrAllocator &Alloc) {
889static MutableArrayRef<uint8_t>
890copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef<uint8_t> &AlignedMem) {
547891 size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
548892 assert(Size >= 4 && "record too short");
549893 assert(Size <= MaxRecordLength && "record too long");
550 void *Mem = Alloc.Allocate(Size, 4);
894 assert(AlignedMem.size() >= Size && "didn't preallocate enough");
551895
552896 // 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);
554899 memcpy(NewData.data(), Sym.data().data(), Sym.length());
555900 memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
556901
557902 // Update the record prefix length. It should point to the beginning of the
558903 // next record.
559 auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem);
904 auto *Prefix = reinterpret_cast<RecordPrefix *>(NewData.data());
560905 Prefix->RecordLen = Size - 2;
561906 return NewData;
562907}
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
597909struct ScopeRecord {
598910 ulittle32_t PtrParent;
599911 ulittle32_t PtrEnd;
......@@ -625,11 +937,10 @@ static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
625937 S.OpeningRecord->PtrEnd = CurOffset;
626938}
627939
628static bool symbolGoesInModuleStream(const CVSymbol &Sym) {
940static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) {
629941 switch (Sym.kind()) {
630942 case SymbolKind::S_GDATA32:
631943 case SymbolKind::S_CONSTANT:
632 case SymbolKind::S_UDT:
633944 // We really should not be seeing S_PROCREF and S_LPROCREF in the first place
634945 // since they are synthesized by the linker in response to S_GPROC32 and
635946 // 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) {
637948 case SymbolKind::S_PROCREF:
638949 case SymbolKind::S_LPROCREF:
639950 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;
640954 // S_GDATA32 does not go in the module stream, but S_LDATA32 does.
641955 case SymbolKind::S_LDATA32:
642956 default:
......@@ -644,7 +958,7 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym) {
644958 }
645959}
646960
647static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) {
961static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) {
648962 switch (Sym.kind()) {
649963 case SymbolKind::S_CONSTANT:
650964 case SymbolKind::S_GDATA32:
......@@ -658,20 +972,16 @@ static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) {
658972 case SymbolKind::S_PROCREF:
659973 case SymbolKind::S_LPROCREF:
660974 return true;
661 // FIXME: For now, we drop all S_UDT symbols (i.e. they don't go in the
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.
975 // S_UDT records go in the globals stream if it is a global S_UDT.
667976 case SymbolKind::S_UDT:
977 return IsGlobalScope;
668978 default:
669979 return false;
670980 }
671981}
672982
673static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,
674 const CVSymbol &Sym) {
983static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex,
984 unsigned SymOffset, const CVSymbol &Sym) {
675985 switch (Sym.kind()) {
676986 case SymbolKind::S_CONSTANT:
677987 case SymbolKind::S_UDT:
......@@ -687,12 +997,12 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,
687997 if (Sym.kind() == SymbolKind::S_LPROC32)
688998 K = SymbolRecordKind::LocalProcRef;
689999 ProcRefSym PS(K);
690 PS.Module = static_cast<uint16_t>(File.ModuleDBI->getModuleIndex());
1000 PS.Module = ModIndex;
6911001 // For some reason, MSVC seems to add one to this value.
6921002 ++PS.Module;
6931003 PS.Name = getSymbolName(Sym);
6941004 PS.SumName = 0;
695 PS.SymOffset = File.ModuleDBI->getNextSymbolOffset();
1005 PS.SymOffset = SymOffset;
6961006 Builder.addGlobalSymbol(PS);
6971007 break;
6981008 }
......@@ -701,20 +1011,62 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File,
7011011 }
7021012}
7031013
704static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File,
705 pdb::GSIStreamBuilder &GsiBuilder,
706 const CVIndexMap &IndexMap,
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.
1014void PDBLinker::mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
1015 std::vector<ulittle32_t *> &StringTableRefs,
1016 BinaryStreamRef SymData) {
7121017 ArrayRef<uint8_t> SymsBuffer;
7131018 cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer));
7141019 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;
7161025 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
7181070 // Discover type index references in the record. Skip it if we don't
7191071 // know where they are.
7201072 SmallVector<TiReference, 32> TypeRefs;
......@@ -724,57 +1076,62 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File,
7241076 return Error::success();
7251077 }
7261078
727 // Copy the symbol record so we can mutate it.
728 MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc);
729
7301079 // Re-map all the type index references.
731 MutableArrayRef<uint8_t> Contents =
732 NewData.drop_front(sizeof(RecordPrefix));
733 remapTypesInSymbolRecord(File, Sym.kind(), Contents, IndexMap,
1080 remapTypesInSymbolRecord(File, Sym.kind(), RecordBytes, IndexMap,
7341081 TypeRefs);
7351082
7361083 // An object file may have S_xxx_ID symbols, but these get converted to
7371084 // "real" symbols in a PDB.
738 translateIdSymbols(NewData, IDTable);
1085 translateIdSymbols(RecordBytes, getIDTable());
1086 Sym = CVSymbol(symbolKind(RecordBytes), RecordBytes);
7391087
7401088 // If this record refers to an offset in the object file's string table,
7411089 // add that item to the global PDB string table and re-write the index.
742 recordStringTableReferences(Sym.kind(), Contents, StringTableRefs);
743
744 SymbolKind NewKind = symbolKind(NewData);
1090 recordStringTableReferences(Sym.kind(), RecordBytes, StringTableRefs);
7451091
7461092 // Fill in "Parent" and "End" fields by maintaining a stack of scopes.
747 CVSymbol NewSym(NewKind, NewData);
748 if (symbolOpensScope(NewKind))
749 scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(),
750 NewSym);
751 else if (symbolEndsScope(NewKind))
752 scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File);
1093 if (symbolOpensScope(Sym.kind()))
1094 scopeStackOpen(Scopes, CurSymOffset, Sym);
1095 else if (symbolEndsScope(Sym.kind()))
1096 scopeStackClose(Scopes, CurSymOffset, File);
7531097
7541098 // Add the symbol to the globals stream if necessary. Do this before
7551099 // adding the symbol to the module since we may need to get the next
7561100 // symbol offset, and writing to the module's symbol stream will update
7571101 // that offset.
758 if (symbolGoesInGlobalsStream(NewSym))
759 addGlobalSymbol(GsiBuilder, *File, NewSym);
760
761 // Add the symbol to the module.
762 if (symbolGoesInModuleStream(NewSym))
763 File->ModuleDBI->addSymbol(NewSym);
1102 if (symbolGoesInGlobalsStream(Sym, Scopes.empty()))
1103 addGlobalSymbol(Builder.getGsiBuilder(),
1104 File->ModuleDBI->getModuleIndex(), CurSymOffset, Sym);
1105
1106 if (symbolGoesInModuleStream(Sym, Scopes.empty())) {
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 }
7641119 return Error::success();
765 });
766 cantFail(std::move(EC));
1120 }));
1121
1122 // Add any remaining symbols we've accumulated.
1123 File->ModuleDBI->addSymbolsInBulk(BulkSymbols);
7671124}
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.
7701127static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
771 SectionChunk *DebugChunk) {
772 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
773 assert(DebugChunk->OutputSectionOff == 0 &&
1128 SectionChunk &DebugChunk) {
1129 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
1130 assert(DebugChunk.OutputSectionOff == 0 &&
7741131 "debug sections should not be in output sections");
775 DebugChunk->writeTo(Buffer);
776 return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
777 ".debug$S");
1132 DebugChunk.readRelocTargets();
1133 DebugChunk.writeTo(Buffer);
1134 return makeArrayRef(Buffer, DebugChunk.getSize());
7781135}
7791136
7801137static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
......@@ -803,25 +1160,137 @@ static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
8031160 return SC;
8041161}
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;
8071276 // Add a module descriptor for every object file. We need to put an absolute
8081277 // path to the object into the PDB. If this is a plain object, we make its
8091278 // path absolute. If it's an object in an archive, we make the archive path
8101279 // absolute.
8111280 bool InArchive = !File->ParentName.empty();
8121281 SmallString<128> Path = InArchive ? File->ParentName : File->getName();
813 sys::fs::make_absolute(Path);
814 sys::path::native(Path, sys::path::Style::windows);
1282 pdbMakeAbsolute(Path);
8151283 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));
8181287 File->ModuleDBI->setObjFileName(Path);
8191288
8201289 auto Chunks = File->getChunks();
8211290 uint32_t Modi = File->ModuleDBI->getModuleIndex();
8221291 for (Chunk *C : Chunks) {
8231292 auto *SecChunk = dyn_cast<SectionChunk>(C);
824 if (!SecChunk || !SecChunk->isLive())
1293 if (!SecChunk || !SecChunk->Live)
8251294 continue;
8261295 pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);
8271296 File->ModuleDBI->setFirstSectionContrib(SC);
......@@ -833,119 +1302,54 @@ void PDBLinker::addObjFile(ObjFile *File) {
8331302 // the PDB first, so that we can get the map from object file type and item
8341303 // indices to PDB type and item indices.
8351304 CVIndexMap ObjectIndexMap;
836 auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);
1305 auto IndexMapResult =
1306 mergeDebugT(File, ExternIndexMap ? ExternIndexMap : &ObjectIndexMap);
8371307
8381308 // If the .debug$T sections fail to merge, assume there is no debug info.
8391309 if (!IndexMapResult) {
840 warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +
841 toString(IndexMapResult.takeError()));
1310 if (!Config->WarnDebugInfoUnusable) {
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())));
8421318 return;
8431319 }
8441320
845 const CVIndexMap &IndexMap = *IndexMapResult;
846
8471321 ScopedTimer T(SymbolMergingTimer);
8481322
849 // Now do all live .debug$S sections.
850 DebugStringTableSubsectionRef CVStrTab;
851 DebugChecksumsSubsectionRef Checksums;
852 std::vector<ulittle32_t *> StringTableReferences;
1323 DebugSHandler DSH(*this, *File, *IndexMapResult);
1324 // Now do all live .debug$S and .debug$F sections.
8531325 for (SectionChunk *DebugChunk : File->getDebugChunks()) {
854 if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
1326 if (!DebugChunk->Live || DebugChunk->getSize() == 0)
8551327 continue;
8561328
857 ArrayRef<uint8_t> RelocatedDebugContents =
858 relocateDebugChunk(Alloc, DebugChunk);
859 if (RelocatedDebugContents.empty())
1329 if (DebugChunk->getSectionName() == ".debug$S") {
1330 DSH.handleDebugS(*DebugChunk);
8601331 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 }
8991332 }
900 }
9011333
902 // We should have seen all debug subsections across the entire object file now
903 // which means that if a StringTable subsection and Checksums subsection were
904 // present, now is the time to handle them.
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");
1334 if (DebugChunk->getSectionName() == ".debug$F") {
1335 ArrayRef<uint8_t> RelocatedDebugContents =
1336 relocateDebugChunk(Alloc, *DebugChunk);
9091337
910 if (!StringTableReferences.empty())
911 warn("No StringTable subsection was encountered, but there are string "
912 "table references");
913 return;
914 }
1338 FixedStreamArray<object::FpoData> FpoRecords;
1339 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
1340 uint32_t Count = RelocatedDebugContents.size() / sizeof(object::FpoData);
1341 ExitOnErr(Reader.readArray(FpoRecords, Count));
9151342
916 // Rewrite each string table reference based on the value that the string
917 // assumes in the final PDB.
918 for (ulittle32_t *Ref : StringTableReferences) {
919 auto ExpectedString = CVStrTab.getString(*Ref);
920 if (!ExpectedString) {
921 warn("Invalid string table reference");
922 consumeError(ExpectedString.takeError());
1343 // These are already relocated and don't refer to the string table, so we
1344 // can just copy it.
1345 for (const object::FpoData &FD : FpoRecords)
1346 DbiBuilder.addOldFpoData(FD);
9231347 continue;
9241348 }
925
926 *Ref = PDBStrTab.insert(*ExpectedString);
9271349 }
9281350
929 // Make a new file checksum table that refers to offsets in the PDB-wide
930 // string table. Generally the string table subsection appears after the
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));
1351 // Do any post-processing now that all .debug$S sections have been processed.
1352 DSH.finish();
9491353}
9501354
9511355static PublicSym32 createPublic(Defined *Def) {
......@@ -977,13 +1381,8 @@ void PDBLinker::addObjectsToPDB() {
9771381
9781382 // Construct TPI and IPI stream contents.
9791383 ScopedTimer T2(TpiStreamLayoutTimer);
980 if (Config->DebugGHashes) {
981 addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable);
982 addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable);
983 } else {
984 addTypeInfo(Builder.getTpiBuilder(), TypeTable);
985 addTypeInfo(Builder.getIpiBuilder(), IDTable);
986 }
1384 addTypeInfo(Builder.getTpiBuilder(), getTypeTable());
1385 addTypeInfo(Builder.getIpiBuilder(), getIDTable());
9871386 T2.stop();
9881387
9891388 ScopedTimer T3(GlobalsLayoutTimer);
......@@ -999,10 +1398,10 @@ void PDBLinker::addObjectsToPDB() {
9991398
10001399 if (!Publics.empty()) {
10011400 // Sort the public symbols and add them to the stream.
1002 std::sort(Publics.begin(), Publics.end(),
1003 [](const PublicSym32 &L, const PublicSym32 &R) {
1004 return L.Name < R.Name;
1005 });
1401 sort(parallel::par, Publics.begin(), Publics.end(),
1402 [](const PublicSym32 &L, const PublicSym32 &R) {
1403 return L.Name < R.Name;
1404 });
10061405 for (const PublicSym32 &Pub : Publics)
10071406 GsiBuilder.addPublicSymbol(Pub);
10081407 }
......@@ -1037,6 +1436,32 @@ static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {
10371436 }
10381437}
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
10401465static void addCommonLinkerModuleSymbols(StringRef Path,
10411466 pdb::DbiModuleDescriptorBuilder &Mod,
10421467 BumpPtrAllocator &Allocator) {
......@@ -1072,14 +1497,17 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
10721497 CS.setLanguage(SourceLanguage::Link);
10731498
10741499 ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();
1075 std::string ArgStr = llvm::join(Args, " ");
1500 std::string ArgStr = quote(Args);
10761501 EBS.Fields.push_back("cwd");
10771502 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;
10791507 EBS.Fields.push_back(cwd);
10801508 EBS.Fields.push_back("exe");
10811509 SmallString<64> exe = Config->Argv[0];
1082 llvm::sys::fs::make_absolute(exe);
1510 pdbMakeAbsolute(exe);
10831511 EBS.Fields.push_back(exe);
10841512 EBS.Fields.push_back("pdb");
10851513 EBS.Fields.push_back(Path);
......@@ -1111,7 +1539,7 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
11111539void coff::createPDB(SymbolTable *Symtab,
11121540 ArrayRef<OutputSection *> OutputSections,
11131541 ArrayRef<uint8_t> SectionTable,
1114 const llvm::codeview::DebugInfo &BuildId) {
1542 llvm::codeview::DebugInfo *BuildId) {
11151543 ScopedTimer T1(TotalPdbLinkTimer);
11161544 PDBLinker PDB(Symtab);
11171545
......@@ -1121,12 +1549,19 @@ void coff::createPDB(SymbolTable *Symtab,
11211549 PDB.addNatvisFiles();
11221550
11231551 ScopedTimer T2(DiskCommitTimer);
1124 PDB.commit();
1552 codeview::GUID Guid;
1553 PDB.commit(&Guid);
1554 memcpy(&BuildId->PDB70.Signature, &Guid, 16);
11251555}
11261556
1127void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
1557void PDBLinker::initialize(llvm::codeview::DebugInfo *BuildId) {
11281558 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
11301565 // Create streams in MSF for predefined streams, namely
11311566 // PDB, TPI, DBI and IPI.
11321567 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
......@@ -1134,15 +1569,12 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
11341569
11351570 // Add an Info stream.
11361571 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);
11411572 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
1573 InfoBuilder.setHashPDBContentsToGUID(true);
11421574
11431575 // Add an empty DBI stream.
11441576 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1145 DbiBuilder.setAge(BuildId.PDB70.Age);
1577 DbiBuilder.setAge(BuildId->PDB70.Age);
11461578 DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
11471579 DbiBuilder.setMachineType(Config->Machine);
11481580 // Technically we are not link.exe 14.11, but there are known cases where
......@@ -1157,8 +1589,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
11571589 // It's not entirely clear what this is, but the * Linker * module uses it.
11581590 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
11591591 NativePath = Config->PDBPath;
1160 sys::fs::make_absolute(NativePath);
1161 sys::path::native(NativePath, sys::path::Style::windows);
1592 pdbMakeAbsolute(NativePath);
11621593 uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
11631594 auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
11641595 LinkerModule.setPdbFilePathNI(PdbFilePathNI);
......@@ -1167,7 +1598,7 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
11671598 // Add section contributions. They must be ordered by ascending RVA.
11681599 for (OutputSection *OS : OutputSections) {
11691600 addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
1170 for (Chunk *C : OS->getChunks()) {
1601 for (Chunk *C : OS->Chunks) {
11711602 pdb::SectionContrib SC =
11721603 createSectionContrib(C, LinkerModule.getModuleIndex());
11731604 Builder.getDbiBuilder().addSectionContrib(SC);
......@@ -1186,9 +1617,9 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
11861617 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
11871618}
11881619
1189void PDBLinker::commit() {
1620void PDBLinker::commit(codeview::GUID *Guid) {
11901621 // Write to a file.
1191 ExitOnErr(Builder.commit(Config->PDBPath));
1622 ExitOnErr(Builder.commit(Config->PDBPath, Guid));
11921623}
11931624
11941625static Expected<StringRef>
......@@ -1315,20 +1746,26 @@ std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,
13151746 if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
13161747 return {"", 0};
13171748
1318 uint32_t NameIndex;
1319 uint32_t LineNumber;
1749 Optional<uint32_t> NameIndex;
1750 Optional<uint32_t> LineNumber;
13201751 for (LineColumnEntry &Entry : Lines) {
13211752 for (const LineNumberEntry &LN : Entry.LineNumbers) {
1753 LineInfo LI(LN.Flags);
13221754 if (LN.Offset > OffsetInLinetable) {
1755 if (!NameIndex) {
1756 NameIndex = Entry.NameIndex;
1757 LineNumber = LI.getStartLine();
1758 }
13231759 StringRef Filename =
1324 ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
1325 return {Filename, LineNumber};
1760 ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1761 return {Filename, *LineNumber};
13261762 }
1327 LineInfo LI(LN.Flags);
13281763 NameIndex = Entry.NameIndex;
13291764 LineNumber = LI.getStartLine();
13301765 }
13311766 }
1332 StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
1333 return {Filename, LineNumber};
1767 if (!NameIndex)
1768 return {"", 0};
1769 StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1770 return {Filename, *LineNumber};
13341771}
deps/lld/COFF/PDB.h+1-1
......@@ -28,7 +28,7 @@ class SymbolTable;
2828void createPDB(SymbolTable *Symtab,
2929 llvm::ArrayRef<OutputSection *> OutputSections,
3030 llvm::ArrayRef<uint8_t> SectionTable,
31 const llvm::codeview::DebugInfo &BuildId);
31 llvm::codeview::DebugInfo *BuildId);
3232
3333std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C,
3434 uint32_t Addr);
deps/lld/COFF/SymbolTable.cpp+136-49
......@@ -60,16 +60,16 @@ void SymbolTable::addFile(InputFile *File) {
6060}
6161
6262static void errorOrWarn(const Twine &S) {
63 if (Config->Force)
63 if (Config->ForceUnresolved)
6464 warn(S);
6565 else
6666 error(S);
6767}
6868
69// Returns the name of the symbol in SC whose value is <= Addr that is closest
70// to Addr. This is generally the name of the global variable or function whose
71// definition contains Addr.
72static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {
69// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
70// This is generally the global variable or function whose definition contains
71// Addr.
72static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) {
7373 DefinedRegular *Candidate = nullptr;
7474
7575 for (Symbol *S : SC->File->getSymbols()) {
......@@ -81,14 +81,12 @@ static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {
8181 Candidate = D;
8282 }
8383
84 if (!Candidate)
85 return "";
86 return Candidate->getName();
84 return Candidate;
8785}
8886
89static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
87std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
9088 struct Location {
91 StringRef SymName;
89 Symbol *Sym;
9290 std::pair<StringRef, uint32_t> FileLine;
9391 };
9492 std::vector<Location> Locations;
......@@ -102,14 +100,14 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
102100 continue;
103101 std::pair<StringRef, uint32_t> FileLine =
104102 getFileLine(SC, R.VirtualAddress);
105 StringRef SymName = getSymbolName(SC, R.VirtualAddress);
106 if (!FileLine.first.empty() || !SymName.empty())
107 Locations.push_back({SymName, FileLine});
103 Symbol *Sym = getSymbol(SC, R.VirtualAddress);
104 if (!FileLine.first.empty() || Sym)
105 Locations.push_back({Sym, FileLine});
108106 }
109107 }
110108
111109 if (Locations.empty())
112 return "\n>>> referenced by " + toString(File) + "\n";
110 return "\n>>> referenced by " + toString(File);
113111
114112 std::string Out;
115113 llvm::raw_string_ostream OS(Out);
......@@ -119,13 +117,87 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
119117 OS << Loc.FileLine.first << ":" << Loc.FileLine.second
120118 << "\n>>> ";
121119 OS << toString(File);
122 if (!Loc.SymName.empty())
123 OS << ":(" << Loc.SymName << ')';
120 if (Loc.Sym)
121 OS << ":(" << toString(*Loc.Sym) << ')';
124122 }
125 OS << '\n';
126123 return OS.str();
127124}
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
129201void SymbolTable::reportRemainingUndefines() {
130202 SmallPtrSet<Symbol *, 8> Undefs;
131203 DenseMap<Symbol *, Symbol *> LocalImports;
......@@ -169,9 +241,17 @@ void SymbolTable::reportRemainingUndefines() {
169241 }
170242 }
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
172252 // Remaining undefined symbols are not fatal if /force is specified.
173253 // They are replaced with dummy defined symbols.
174 if (Config->Force)
254 if (Config->ForceUnresolved)
175255 replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
176256 Undefs.insert(Sym);
177257 }
......@@ -181,10 +261,10 @@ void SymbolTable::reportRemainingUndefines() {
181261
182262 for (Symbol *B : Config->GCRoot) {
183263 if (Undefs.count(B))
184 errorOrWarn("<root>: undefined symbol: " + B->getName());
264 errorOrWarn("<root>: undefined symbol: " + toString(*B));
185265 if (Config->WarnLocallyDefinedImported)
186266 if (Symbol *Imp = LocalImports.lookup(B))
187 warn("<root>: locally defined symbol imported: " + Imp->getName() +
267 warn("<root>: locally defined symbol imported: " + toString(*Imp) +
188268 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
189269 }
190270
......@@ -195,34 +275,41 @@ void SymbolTable::reportRemainingUndefines() {
195275 if (!Sym)
196276 continue;
197277 if (Undefs.count(Sym))
198 errorOrWarn("undefined symbol: " + Sym->getName() +
278 errorOrWarn("undefined symbol: " + toString(*Sym) +
199279 getSymbolLocations(File, SymIndex));
200280 if (Config->WarnLocallyDefinedImported)
201281 if (Symbol *Imp = LocalImports.lookup(Sym))
202 warn(toString(File) + ": locally defined symbol imported: " +
203 Imp->getName() + " (defined in " + toString(Imp->getFile()) +
204 ") [LNK4217]");
282 warn(toString(File) +
283 ": locally defined symbol imported: " + toString(*Imp) +
284 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
205285 }
206286 }
207287}
208288
209289std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
290 bool Inserted = false;
210291 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
211 if (Sym)
212 return {Sym, false};
213 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
214 Sym->IsUsedInRegularObj = false;
215 Sym->PendingArchiveLoad = false;
216 return {Sym, true};
292 if (!Sym) {
293 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
294 Sym->IsUsedInRegularObj = false;
295 Sym->PendingArchiveLoad = false;
296 Inserted = 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;
217306}
218307
219308Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
220309 bool IsWeakAlias) {
221310 Symbol *S;
222311 bool WasInserted;
223 std::tie(S, WasInserted) = insert(Name);
224 if (!F || !isa<BitcodeFile>(F))
225 S->IsUsedInRegularObj = true;
312 std::tie(S, WasInserted) = insert(Name, F);
226313 if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) {
227314 replaceSymbol<Undefined>(S, Name);
228315 return S;
......@@ -253,14 +340,20 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
253340}
254341
255342void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
256 error("duplicate symbol: " + toString(*Existing) + " in " +
257 toString(Existing->getFile()) + " and in " + toString(NewFile));
343 std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
344 toString(Existing->getFile()) + " and in " +
345 toString(NewFile);
346
347 if (Config->ForceMultiple)
348 warn(Msg);
349 else
350 error(Msg);
258351}
259352
260353Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
261354 Symbol *S;
262355 bool WasInserted;
263 std::tie(S, WasInserted) = insert(N);
356 std::tie(S, WasInserted) = insert(N, nullptr);
264357 S->IsUsedInRegularObj = true;
265358 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
266359 replaceSymbol<DefinedAbsolute>(S, N, Sym);
......@@ -272,7 +365,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
272365Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
273366 Symbol *S;
274367 bool WasInserted;
275 std::tie(S, WasInserted) = insert(N);
368 std::tie(S, WasInserted) = insert(N, nullptr);
276369 S->IsUsedInRegularObj = true;
277370 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
278371 replaceSymbol<DefinedAbsolute>(S, N, VA);
......@@ -284,7 +377,7 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
284377Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
285378 Symbol *S;
286379 bool WasInserted;
287 std::tie(S, WasInserted) = insert(N);
380 std::tie(S, WasInserted) = insert(N, nullptr);
288381 S->IsUsedInRegularObj = true;
289382 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
290383 replaceSymbol<DefinedSynthetic>(S, N, C);
......@@ -298,9 +391,7 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
298391 SectionChunk *C) {
299392 Symbol *S;
300393 bool WasInserted;
301 std::tie(S, WasInserted) = insert(N);
302 if (!isa<BitcodeFile>(F))
303 S->IsUsedInRegularObj = true;
394 std::tie(S, WasInserted) = insert(N, F);
304395 if (WasInserted || !isa<DefinedRegular>(S))
305396 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,
306397 /*IsExternal*/ true, Sym, C);
......@@ -314,9 +405,7 @@ SymbolTable::addComdat(InputFile *F, StringRef N,
314405 const coff_symbol_generic *Sym) {
315406 Symbol *S;
316407 bool WasInserted;
317 std::tie(S, WasInserted) = insert(N);
318 if (!isa<BitcodeFile>(F))
319 S->IsUsedInRegularObj = true;
408 std::tie(S, WasInserted) = insert(N, F);
320409 if (WasInserted || !isa<DefinedRegular>(S)) {
321410 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
322411 /*IsExternal*/ true, Sym, nullptr);
......@@ -331,9 +420,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
331420 const coff_symbol_generic *Sym, CommonChunk *C) {
332421 Symbol *S;
333422 bool WasInserted;
334 std::tie(S, WasInserted) = insert(N);
335 if (!isa<BitcodeFile>(F))
336 S->IsUsedInRegularObj = true;
423 std::tie(S, WasInserted) = insert(N, F);
337424 if (WasInserted || !isa<DefinedCOFF>(S))
338425 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
339426 else if (auto *DC = dyn_cast<DefinedCommon>(S))
......@@ -345,7 +432,7 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
345432Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
346433 Symbol *S;
347434 bool WasInserted;
348 std::tie(S, WasInserted) = insert(N);
435 std::tie(S, WasInserted) = insert(N, nullptr);
349436 S->IsUsedInRegularObj = true;
350437 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
351438 replaceSymbol<DefinedImportData>(S, N, F);
......@@ -360,7 +447,7 @@ Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
360447 uint16_t Machine) {
361448 Symbol *S;
362449 bool WasInserted;
363 std::tie(S, WasInserted) = insert(Name);
450 std::tie(S, WasInserted) = insert(Name, nullptr);
364451 S->IsUsedInRegularObj = true;
365452 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
366453 replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);
deps/lld/COFF/SymbolTable.h+8
......@@ -54,6 +54,9 @@ public:
5454 // symbols.
5555 void reportRemainingUndefines();
5656
57 void loadMinGWAutomaticImports();
58 bool handleMinGWAutomaticImport(Symbol *Sym, StringRef Name);
59
5760 // Returns a list of chunks of selected symbols.
5861 std::vector<Chunk *> getChunks();
5962
......@@ -108,7 +111,10 @@ public:
108111 }
109112
110113private:
114 /// Inserts symbol if not already present.
111115 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);
112118 StringRef findByPrefix(StringRef Prefix);
113119
114120 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
......@@ -117,6 +123,8 @@ private:
117123
118124extern SymbolTable *Symtab;
119125
126std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex);
127
120128} // namespace coff
121129} // namespace lld
122130
deps/lld/COFF/Symbols.cpp+8-1
......@@ -54,7 +54,7 @@ InputFile *Symbol::getFile() {
5454
5555bool Symbol::isLive() const {
5656 if (auto *R = dyn_cast<DefinedRegular>(this))
57 return R->getChunk()->isLive();
57 return R->getChunk()->Live;
5858 if (auto *Imp = dyn_cast<DefinedImportData>(this))
5959 return Imp->File->Live;
6060 if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
......@@ -63,6 +63,13 @@ bool Symbol::isLive() const {
6363 return true;
6464}
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
6673COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
6774 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
6875 if (SymSize == sizeof(coff_symbol16))
deps/lld/COFF/Symbols.h+9-5
......@@ -39,9 +39,9 @@ class Symbol {
3939public:
4040 enum Kind {
4141 // 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 cheapest
42 // symbols as those are the most prevalent and the zero tag is the cheapest
4343 // to set. Among the defined kinds, the lower the kind is preferred over
44 // the higher kind when testing wether one symbol should take precedence
44 // the higher kind when testing whether one symbol should take precedence
4545 // over another.
4646 DefinedRegularKind = 0,
4747 DefinedCommonKind,
......@@ -66,6 +66,8 @@ public:
6666 // Returns the symbol name.
6767 StringRef getName();
6868
69 void replaceKeepingName(Symbol *Other, size_t Size);
70
6971 // Returns the file from which this symbol was created.
7072 InputFile *getFile();
7173
......@@ -78,7 +80,7 @@ protected:
7880 explicit Symbol(Kind K, StringRef N = "")
7981 : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
8082 WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
81 Name(N) {}
83 IsRuntimePseudoReloc(false), Name(N) {}
8284
8385 const unsigned SymbolKind : 8;
8486 unsigned IsExternal : 1;
......@@ -102,6 +104,8 @@ public:
102104 /// True if we've already added this symbol to the list of GC roots.
103105 unsigned IsGCRoot : 1;
104106
107 unsigned IsRuntimePseudoReloc : 1;
108
105109protected:
106110 StringRef Name;
107111};
......@@ -331,8 +335,8 @@ private:
331335 Chunk *Data;
332336};
333337
334// If you have a symbol "__imp_foo" in your object file, a symbol name
335// "foo" becomes automatically available as a pointer to "__imp_foo".
338// If you have a symbol "foo" in your object file, a symbol name
339// "__imp_foo" becomes automatically available as a pointer to "foo".
336340// This class is for such automatically-created symbols.
337341// Yes, this is an odd feature. We didn't intend to implement that.
338342// This is here just for compatibility with MSVC.
deps/lld/COFF/Writer.cpp+601-148
......@@ -77,36 +77,38 @@ static const int SectorSize = 512;
7777static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram);
7878static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8");
7979
80static const int NumberfOfDataDirectory = 16;
80static const int NumberOfDataDirectory = 16;
8181
8282namespace {
8383
8484class DebugDirectoryChunk : public Chunk {
8585public:
86 DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}
86 DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
87 : Records(R), WriteRepro(WriteRepro) {}
8788
8889 size_t getSize() const override {
89 return Records.size() * sizeof(debug_directory);
90 return (Records.size() + int(WriteRepro)) * sizeof(debug_directory);
9091 }
9192
9293 void writeTo(uint8_t *B) const override {
9394 auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
9495
9596 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();
10397 OutputSection *OS = Record->getOutputSection();
10498 uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());
105 D->PointerToRawData = Offs;
106
107 TimeDateStamps.push_back(&D->TimeDateStamp);
99 fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(),
100 Record->getRVA(), Offs);
108101 ++D;
109102 }
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 }
110112 }
111113
112114 void setTimeDateStamp(uint32_t TimeDateStamp) {
......@@ -115,8 +117,23 @@ public:
115117 }
116118
117119private:
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
118134 mutable std::vector<support::ulittle32_t *> TimeDateStamps;
119135 const std::vector<Chunk *> &Records;
136 bool WriteRepro;
120137};
121138
122139class CVDebugRecordChunk : public Chunk {
......@@ -150,14 +167,22 @@ private:
150167 void createSections();
151168 void createMiscChunks();
152169 void createImportTables();
170 void appendImportThunks();
171 void locateImportTables(
172 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
153173 void createExportTable();
154174 void mergeSections();
175 void readRelocTargets();
176 void removeUnusedSections();
155177 void assignAddresses();
178 void finalizeAddresses();
156179 void removeEmptySections();
157180 void createSymbolAndStringTable();
158181 void openFile(StringRef OutputPath);
159182 template <typename PEHeaderTy> void writeHeader();
160183 void createSEHTable();
184 void createRuntimePseudoRelocs();
185 void insertCtorDtorSymbols();
161186 void createGuardCFTables();
162187 void markSymbolsForRVATable(ObjFile *File,
163188 ArrayRef<SectionChunk *> SymIdxChunks,
......@@ -168,6 +193,7 @@ private:
168193 void writeSections();
169194 void writeBuildId();
170195 void sortExceptionTable();
196 void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
171197
172198 llvm::Optional<coff_symbol16> createSymbol(Defined *D);
173199 size_t addEntryToStringTable(StringRef Str);
......@@ -184,6 +210,10 @@ private:
184210 std::vector<char> Strtab;
185211 std::vector<llvm::object::coff_symbol16> OutputSymtab;
186212 IdataContents Idata;
213 Chunk *ImportTableStart = nullptr;
214 uint64_t ImportTableSize = 0;
215 Chunk *IATStart = nullptr;
216 uint64_t IATSize = 0;
187217 DelayLoadContents DelayIdata;
188218 EdataContents Edata;
189219 bool SetNoSEHCharacteristic = false;
......@@ -191,7 +221,6 @@ private:
191221 DebugDirectoryChunk *DebugDirectory = nullptr;
192222 std::vector<Chunk *> DebugRecords;
193223 CVDebugRecordChunk *BuildId = nullptr;
194 Optional<codeview::DebugInfo> PreviousBuildId;
195224 ArrayRef<uint8_t> SectionTable;
196225
197226 uint64_t FileSize;
......@@ -209,6 +238,8 @@ private:
209238 OutputSection *DidatSec;
210239 OutputSection *RsrcSec;
211240 OutputSection *RelocSec;
241 OutputSection *CtorsSec;
242 OutputSection *DtorsSec;
212243
213244 // The first and last .pdata sections in the output file.
214245 //
......@@ -237,6 +268,11 @@ void OutputSection::addChunk(Chunk *C) {
237268 C->setOutputSection(this);
238269}
239270
271void OutputSection::insertChunkAtStart(Chunk *C) {
272 Chunks.insert(Chunks.begin(), C);
273 C->setOutputSection(this);
274}
275
240276void OutputSection::setPermissions(uint32_t C) {
241277 Header.Characteristics &= ~PermMask;
242278 Header.Characteristics |= C;
......@@ -267,77 +303,232 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
267303} // namespace coff
268304} // namespace lld
269305
270// PDBs are matched against executables using a build id which consists of three
271// components:
272// 1. A 16-bit GUID
273// 2. An age
274// 3. A time stamp.
275//
276// Debuggers and symbol servers match executables against debug info by checking
277// each of these components of the EXE/DLL against the corresponding value in
278// the PDB and failing a match if any of the components differ. In the case of
279// symbol servers, symbols are cached in a folder that is a function of the
280// GUID. As a result, in order to avoid symbol cache pollution where every
281// incremental build copies a new PDB to the symbol cache, we must try to re-use
282// the existing GUID if one exists, but bump the age. This way the match will
283// fail, so the symbol cache knows to use the new PDB, but the GUID matches, so
284// it overwrites the existing item in the symbol cache rather than making a new
285// one.
286static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) {
287 // We don't need to incrementally update a previous build id if we're not
288 // writing codeview debug info.
289 if (!Config->Debug)
290 return None;
306// Check whether the target address S is in range from a relocation
307// of type RelType at address P.
308static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
309 if (Config->Machine == ARMNT) {
310 int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
311 switch (RelType) {
312 case IMAGE_REL_ARM_BRANCH20T:
313 return isInt<21>(Diff);
314 case IMAGE_REL_ARM_BRANCH24T:
315 case IMAGE_REL_ARM_BLX23T:
316 return isInt<25>(Diff);
317 default:
318 return true;
319 }
320 } else if (Config->Machine == ARM64) {
321 int64_t Diff = AbsoluteDifference(S, P) + Margin;
322 switch (RelType) {
323 case IMAGE_REL_ARM64_BRANCH26:
324 return isInt<28>(Diff);
325 case IMAGE_REL_ARM64_BRANCH19:
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);
293 if (!ExpectedBinary) {
294 consumeError(ExpectedBinary.takeError());
295 return None;
337// Return the last thunk for the given target if it is in range,
338// or create a new one.
339static std::pair<Defined *, bool>
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");
296355 }
356 Defined *D = make<DefinedSynthetic>("", C);
357 LastThunk = D;
358 return {D, true};
359}
297360
298 auto Binary = std::move(*ExpectedBinary);
299 if (!Binary.getBinary()->isCOFF())
300 return None;
361// This checks all relocations, and for any relocation which isn't in range
362// it adds a thunk after the section chunk that contains the relocation.
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;
303 COFFObjectFile File(Binary.getBinary()->getMemoryBufferRef(), EC);
304 if (EC)
305 return None;
402 uint64_t S = Sym->getRVA();
306403
307 // If the machine of the binary we're outputting doesn't match the machine
308 // of the existing binary, don't try to re-use the build id.
309 if (File.is64() != Config->is64() || File.getMachine() != Config->Machine)
310 return None;
404 if (isInRange(Rel.Type, S, P, Margin))
405 continue;
406
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()) {
313 if (DebugDir.Type != IMAGE_DEBUG_TYPE_CODEVIEW)
429// Verify that all relocations are in range, with no extra margin requirements.
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)
314434 continue;
315435
316 const codeview::DebugInfo *ExistingDI = nullptr;
317 StringRef PDBFileName;
318 if (auto EC = File.getDebugPDBInfo(ExistingDI, PDBFileName)) {
319 (void)EC;
320 return None;
436 for (size_t J = 0, E = SC->Relocs.size(); J < E; ++J) {
437 const coff_relocation &Rel = SC->Relocs[J];
438 Symbol *RelocTarget = SC->RelocTargets[J];
439
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;
321449 }
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;
327450 }
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 }
329517}
330518
331519// The main function of the writer.
332520void Writer::run() {
333521 ScopedTimer T1(CodeLayoutTimer);
334522
523 createImportTables();
335524 createSections();
336525 createMiscChunks();
337 createImportTables();
526 appendImportThunks();
338527 createExportTable();
339528 mergeSections();
340 assignAddresses();
529 readRelocTargets();
530 removeUnusedSections();
531 finalizeAddresses();
341532 removeEmptySections();
342533 setSectionPermissions();
343534 createSymbolAndStringTable();
......@@ -346,9 +537,6 @@ void Writer::run() {
346537 fatal("image size (" + Twine(FileSize) + ") " +
347538 "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);
352540 openFile(Config->OutputFile);
353541 if (Config->is64()) {
354542 writeHeader<pe32plus_header>();
......@@ -357,14 +545,14 @@ void Writer::run() {
357545 }
358546 writeSections();
359547 sortExceptionTable();
360 writeBuildId();
361548
362549 T1.stop();
363550
364551 if (!Config->PDBPath.empty() && Config->Debug) {
365552 assert(BuildId);
366 createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId);
553 createPDB(Symtab, OutputSections, SectionTable, BuildId->BuildId);
367554 }
555 writeBuildId();
368556
369557 writeMapFile(OutputSections);
370558
......@@ -396,6 +584,110 @@ static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {
396584 });
397585}
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
399691// Create output section objects and add them to OutputSections.
400692void Writer::createSections() {
401693 // First, create the builtin sections.
......@@ -429,12 +721,14 @@ void Writer::createSections() {
429721 DidatSec = CreateSection(".didat", DATA | R);
430722 RsrcSec = CreateSection(".rsrc", DATA | R);
431723 RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);
724 CtorsSec = CreateSection(".ctors", DATA | R | W);
725 DtorsSec = CreateSection(".dtors", DATA | R | W);
432726
433727 // Then bin chunks by name and output characteristics.
434728 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
435729 for (Chunk *C : Symtab->getChunks()) {
436730 auto *SC = dyn_cast<SectionChunk>(C);
437 if (SC && !SC->isLive()) {
731 if (SC && !SC->Live) {
438732 if (Config->Verbose)
439733 SC->printDiscardedMessage();
440734 continue;
......@@ -442,26 +736,43 @@ void Writer::createSections() {
442736 Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
443737 }
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
445748 // Process an /order option.
446749 if (!Config->Order.empty())
447750 for (auto &Pair : Map)
448751 sortBySectionOrder(Pair.second);
449752
753 if (HasIdata)
754 locateImportTables(Map);
755
450756 // Then create an OutputSection for each section.
451757 // '$' and all following characters in input section names are
452758 // discarded when determining output section. So, .text$foo
453759 // contributes to .text, for example. See PE/COFF spec 3.2.
454 for (auto Pair : Map) {
760 for (auto &Pair : Map) {
455761 StringRef Name = getOutputSectionName(Pair.first.first);
456762 uint32_t OutChars = Pair.first.second;
457763
458 // In link.exe, there is a special case for the I386 target where .CRT
459 // sections are treated as if they have output characteristics DATA | R if
460 // their characteristics are DATA | R | W. This implements the same special
461 // case for all architectures.
462 if (Name == ".CRT")
764 if (Name == ".CRT") {
765 // In link.exe, there is a special case for the I386 target where .CRT
766 // sections are treated as if they have output characteristics DATA | R if
767 // their characteristics are DATA | R | W. This implements the same
768 // special case for all architectures.
463769 OutChars = DATA | R;
464770
771 log("Processing section " + Pair.first.first + " -> " + Name);
772
773 sortCRTSectionChunks(Pair.second);
774 }
775
465776 OutputSection *Sec = CreateSection(Name, OutChars);
466777 std::vector<Chunk *> &Chunks = Pair.second;
467778 for (Chunk *C : Chunks)
......@@ -499,20 +810,20 @@ void Writer::createMiscChunks() {
499810 }
500811
501812 // Create Debug Information Chunks
502 if (Config->Debug) {
503 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
504
505 OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
813 OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
814 if (Config->Debug || Config->Repro) {
815 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords, Config->Repro);
816 DebugInfoSec->addChunk(DebugDirectory);
817 }
506818
819 if (Config->Debug) {
507820 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
508821 // output a PDB no matter what, and this chunk provides the only means of
509822 // allowing a debugger to match a PDB and an executable. So we need it even
510823 // if we're ultimately not going to write CodeView data to the PDB.
511 auto *CVChunk = make<CVDebugRecordChunk>();
512 BuildId = CVChunk;
513 DebugRecords.push_back(CVChunk);
824 BuildId = make<CVDebugRecordChunk>();
825 DebugRecords.push_back(BuildId);
514826
515 DebugInfoSec->addChunk(DebugDirectory);
516827 for (Chunk *C : DebugRecords)
517828 DebugInfoSec->addChunk(C);
518829 }
......@@ -524,6 +835,12 @@ void Writer::createMiscChunks() {
524835 // Create /guard:cf tables if requested.
525836 if (Config->GuardCF != GuardCFLevel::Off)
526837 createGuardCFTables();
838
839 if (Config->MinGW) {
840 createRuntimePseudoRelocs();
841
842 insertCtorDtorSymbols();
843 }
527844}
528845
529846// Create .idata section for the DLL-imported symbol table.
......@@ -531,9 +848,6 @@ void Writer::createMiscChunks() {
531848// IdataContents class abstracted away the details for us,
532849// so we just let it create chunks and add them to the section.
533850void Writer::createImportTables() {
534 if (ImportFile::Instances.empty())
535 return;
536
537851 // Initialize DLLOrder so that import entries are ordered in
538852 // the same order as in the command line. (That affects DLL
539853 // initialization order, and this ordering is MSVC-compatible.)
......@@ -545,14 +859,6 @@ void Writer::createImportTables() {
545859 if (Config->DLLOrder.count(DLL) == 0)
546860 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
556862 if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym))
557863 fatal(toString(*File->ImpSym) + " was replaced");
558864 DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym);
......@@ -565,10 +871,25 @@ void Writer::createImportTables() {
565871 Idata.add(ImpSym);
566872 }
567873 }
874}
568875
569 if (!Idata.empty())
570 for (Chunk *C : Idata.getChunks())
571 IdataSec->addChunk(C);
876void Writer::appendImportThunks() {
877 if (ImportFile::Instances.empty())
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
573894 if (!DelayIdata.empty()) {
574895 Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
......@@ -589,6 +910,21 @@ void Writer::createExportTable() {
589910 EdataSec->addChunk(C);
590911}
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
592928// The Windows loader doesn't seem to like empty sections,
593929// so we remove them if any.
594930void Writer::removeEmptySections() {
......@@ -699,9 +1035,9 @@ void Writer::createSymbolAndStringTable() {
6991035}
7001036
7011037void Writer::mergeSections() {
702 if (!PdataSec->getChunks().empty()) {
703 FirstPdata = PdataSec->getChunks().front();
704 LastPdata = PdataSec->getChunks().back();
1038 if (!PdataSec->Chunks.empty()) {
1039 FirstPdata = PdataSec->Chunks.front();
1040 LastPdata = PdataSec->Chunks.back();
7051041 }
7061042
7071043 for (auto &P : Config->Merge) {
......@@ -729,11 +1065,18 @@ void Writer::mergeSections() {
7291065 }
7301066}
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
7321075// Visits all sections to assign incremental, non-overlapping RVAs and
7331076// file offsets.
7341077void Writer::assignAddresses() {
7351078 SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
736 sizeof(data_directory) * NumberfOfDataDirectory +
1079 sizeof(data_directory) * NumberOfDataDirectory +
7371080 sizeof(coff_section) * OutputSections.size();
7381081 SizeOfHeaders +=
7391082 Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
......@@ -746,7 +1089,7 @@ void Writer::assignAddresses() {
7461089 addBaserels();
7471090 uint64_t RawSize = 0, VirtualSize = 0;
7481091 Sec->Header.VirtualAddress = RVA;
749 for (Chunk *C : Sec->getChunks()) {
1092 for (Chunk *C : Sec->Chunks) {
7501093 VirtualSize = alignTo(VirtualSize, C->Alignment);
7511094 C->setRVA(RVA + VirtualSize);
7521095 C->OutputSectionOff = VirtualSize;
......@@ -808,7 +1151,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
8081151 if (!Config->Relocatable)
8091152 COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
8101153 COFF->SizeOfOptionalHeader =
811 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberfOfDataDirectory;
1154 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberOfDataDirectory;
8121155
8131156 // Write PE header
8141157 auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
......@@ -866,7 +1209,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
8661209 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
8671210 if (Config->TerminalServerAware)
8681211 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
869 PE->NumberOfRvaAndSize = NumberfOfDataDirectory;
1212 PE->NumberOfRvaAndSize = NumberOfDataDirectory;
8701213 if (TextSec->getVirtualSize()) {
8711214 PE->BaseOfCode = TextSec->getRVA();
8721215 PE->SizeOfCode = TextSec->getRawSize();
......@@ -875,16 +1218,18 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
8751218
8761219 // Write data directory
8771220 auto *Dir = reinterpret_cast<data_directory *>(Buf);
878 Buf += sizeof(*Dir) * NumberfOfDataDirectory;
1221 Buf += sizeof(*Dir) * NumberOfDataDirectory;
8791222 if (!Config->Exports.empty()) {
8801223 Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();
8811224 Dir[EXPORT_TABLE].Size = Edata.getSize();
8821225 }
883 if (!Idata.empty()) {
884 Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA();
885 Dir[IMPORT_TABLE].Size = Idata.getDirSize();
886 Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA();
887 Dir[IAT].Size = Idata.getIATSize();
1226 if (ImportTableStart) {
1227 Dir[IMPORT_TABLE].RelativeVirtualAddress = ImportTableStart->getRVA();
1228 Dir[IMPORT_TABLE].Size = ImportTableSize;
1229 }
1230 if (IATStart) {
1231 Dir[IAT].RelativeVirtualAddress = IATStart->getRVA();
1232 Dir[IAT].Size = IATSize;
8881233 }
8891234 if (RsrcSec->getVirtualSize()) {
8901235 Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();
......@@ -907,7 +1252,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
9071252 : sizeof(object::coff_tls_directory32);
9081253 }
9091254 }
910 if (Config->Debug) {
1255 if (DebugDirectory) {
9111256 Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
9121257 Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
9131258 }
......@@ -1002,6 +1347,25 @@ static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) {
10021347 RVASet.insert({C, Off});
10031348}
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
10051369// Visit all relocations from all section contributions of this object file and
10061370// mark the relocation target as address-taken.
10071371static void markSymbolsWithRelocations(ObjFile *File,
......@@ -1010,21 +1374,17 @@ static void markSymbolsWithRelocations(ObjFile *File,
10101374 // We only care about live section chunks. Common chunks and other chunks
10111375 // don't generally contain relocations.
10121376 SectionChunk *SC = dyn_cast<SectionChunk>(C);
1013 if (!SC || !SC->isLive())
1377 if (!SC || !SC->Live)
10141378 continue;
10151379
1016 // Look for relocations in this section against symbols in executable output
1017 // sections.
1018 for (Symbol *Ref : SC->symbols()) {
1019 // FIXME: Do further testing to see if the relocation type matters,
1020 // especially for 32-bit where taking the address of something usually
1021 // uses an absolute relocation instead of a relative one.
1022 if (auto *D = dyn_cast_or_null<Defined>(Ref)) {
1023 Chunk *RefChunk = D->getChunk();
1024 OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
1025 if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
1026 addSymbolToRVASet(UsedSymbols, D);
1027 }
1380 for (const coff_relocation &Reloc : SC->Relocs) {
1381 if (Config->Machine == I386 && Reloc.Type == COFF::IMAGE_REL_I386_REL32)
1382 // Ignore relative relocations on x86. On x86_64 they can't be ignored
1383 // since they're also used to compute absolute addresses.
1384 continue;
1385
1386 Symbol *Ref = SC->File->getSymbol(Reloc.SymbolTableIndex);
1387 maybeAddAddressTakenFunction(UsedSymbols, Ref);
10281388 }
10291389 }
10301390}
......@@ -1051,7 +1411,11 @@ void Writer::createGuardCFTables() {
10511411
10521412 // Mark the image entry as address-taken.
10531413 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
10561420 // Ensure sections referenced in the gfid table are 16-byte aligned.
10571421 for (const ChunkAndOffset &C : AddressTakenSyms)
......@@ -1087,7 +1451,7 @@ void Writer::markSymbolsForRVATable(ObjFile *File,
10871451 // is associated with something like a vtable and the vtable is discarded.
10881452 // In this case, the associated gfids section is discarded, and we don't
10891453 // mark the virtual member functions as address-taken by the vtable.
1090 if (!C->isLive())
1454 if (!C->Live)
10911455 continue;
10921456
10931457 // Validate that the contents look like symbol table indices.
......@@ -1134,6 +1498,56 @@ void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
11341498 cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4);
11351499}
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
11371551// Handles /section options to allow users to overwrite
11381552// section attributes.
11391553void Writer::setSectionPermissions() {
......@@ -1160,7 +1574,7 @@ void Writer::writeSections() {
11601574 // ADD instructions).
11611575 if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
11621576 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(),
11641578 [&](Chunk *C) { C->writeTo(SecBuf); });
11651579 }
11661580}
......@@ -1171,25 +1585,10 @@ void Writer::writeBuildId() {
11711585 // timestamp as well as a Guid and Age of the PDB.
11721586 // 2) In all cases, the PE COFF file header also contains a timestamp.
11731587 // 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 into
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).
1588 // PE contents.
11831589 if (Config->Debug) {
11841590 assert(BuildId && "BuildId is not set!");
1185 if (PreviousBuildId.hasValue()) {
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 }
1591 // BuildId->BuildId was filled in when the PDB was written.
11931592 }
11941593
11951594 // At this point the only fields in the COFF file which remain unset are the
......@@ -1201,8 +1600,25 @@ void Writer::writeBuildId() {
12011600 Buffer->getBufferSize());
12021601
12031602 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
12041610 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
12071623 if (DebugDirectory)
12081624 DebugDirectory->setTimeDateStamp(Timestamp);
......@@ -1240,6 +1656,42 @@ void Writer::sortExceptionTable() {
12401656 errs() << "warning: don't know how to handle .pdata.\n";
12411657}
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
12431695OutputSection *Writer::findSection(StringRef Name) {
12441696 for (OutputSection *Sec : OutputSections)
12451697 if (Sec->Name == Name)
......@@ -1259,12 +1711,13 @@ uint32_t Writer::getSizeOfInitializedData() {
12591711void Writer::addBaserels() {
12601712 if (!Config->Relocatable)
12611713 return;
1714 RelocSec->Chunks.clear();
12621715 std::vector<Baserel> V;
12631716 for (OutputSection *Sec : OutputSections) {
12641717 if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
12651718 continue;
12661719 // Collect all locations for base relocations.
1267 for (Chunk *C : Sec->getChunks())
1720 for (Chunk *C : Sec->Chunks)
12681721 C->getBaserels(&V);
12691722 // Add the addresses to .reloc section.
12701723 if (!V.empty())
deps/lld/COFF/Writer.h+4-2
......@@ -34,8 +34,8 @@ public:
3434 Header.Characteristics = Chars;
3535 }
3636 void addChunk(Chunk *C);
37 void insertChunkAtStart(Chunk *C);
3738 void merge(OutputSection *Other);
38 ArrayRef<Chunk *> getChunks() { return Chunks; }
3939 void addPermissions(uint32_t C);
4040 void setPermissions(uint32_t C);
4141 uint64_t getRVA() { return Header.VirtualAddress; }
......@@ -62,9 +62,11 @@ public:
6262 llvm::StringRef Name;
6363 llvm::object::coff_section Header = {};
6464
65 std::vector<Chunk *> Chunks;
66 std::vector<Chunk *> OrigChunks;
67
6568private:
6669 uint32_t StringTableOff = 0;
67 std::vector<Chunk *> Chunks;
6870};
6971
7072}
deps/lld/Common/Args.cpp+8-1
......@@ -13,6 +13,7 @@
1313#include "llvm/ADT/StringExtras.h"
1414#include "llvm/ADT/StringRef.h"
1515#include "llvm/Option/ArgList.h"
16#include "llvm/Support/Path.h"
1617
1718using namespace llvm;
1819using namespace lld;
......@@ -40,7 +41,7 @@ std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {
4041
4142uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id,
4243 StringRef Key, uint64_t Default) {
43 for (auto *Arg : Args.filtered(Id)) {
44 for (auto *Arg : Args.filtered_reverse(Id)) {
4445 std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
4546 if (KV.first == Key) {
4647 uint64_t Result = Default;
......@@ -64,3 +65,9 @@ std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) {
6465 }
6566 return Ret;
6667}
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() {
4747}
4848
4949void lld::exitLld(int Val) {
50 // Delete the output buffer so that any tempory file is deleted.
51 errorHandler().OutputBuffer.reset();
50 // Delete any temporary file, while keeping the memory mapping open.
51 if (errorHandler().OutputBuffer)
52 errorHandler().OutputBuffer->discard();
5253
5354 // Dealloc/destroy ManagedStatic variables before calling
5455 // _exit(). In a non-LTO build, this is a nop. In an LTO
deps/lld/Common/Strings.cpp+14-19
......@@ -16,14 +16,6 @@
1616#include <mutex>
1717#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
2719using namespace llvm;
2820using namespace lld;
2921
......@@ -45,18 +37,21 @@ Optional<std::string> lld::demangleItanium(StringRef Name) {
4537 return S;
4638}
4739
48Optional<std::string> lld::demangleMSVC(StringRef S) {
49#if defined(_MSC_VER)
50 // UnDecorateSymbolName is not thread-safe, so we need a mutex.
51 static std::mutex Mu;
52 std::lock_guard<std::mutex> Lock(Mu);
40Optional<std::string> lld::demangleMSVC(StringRef Name) {
41 std::string Prefix;
42 if (Name.consume_front("__imp_"))
43 Prefix = "__declspec(dllimport) ";
44
45 // Demangle only C++ names.
46 if (!Name.startswith("?"))
47 return None;
5348
54 char Buf[4096];
55 if (S.startswith("?"))
56 if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
57 return std::string(Buf, Len);
58#endif
59 return None;
49 char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
50 if (!Buf)
51 return None;
52 std::string S(Buf);
53 free(Buf);
54 return Prefix + S;
6055}
6156
6257StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
deps/lld/Common/TargetOptionsCommandFlags.cpp+1
......@@ -32,3 +32,4 @@ llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {
3232}
3333
3434std::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,
356356 }
357357
358358 uint64_t PatchOff = 0;
359 const uint8_t *Buf = IS->Data.begin();
359 const uint8_t *Buf = IS->data().begin();
360360 const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
361361 uint32_t Instr1 = *InstBuf++;
362362 uint32_t Instr2 = *InstBuf++;
......@@ -411,7 +411,7 @@ uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {
411411void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {
412412 // Copy the instruction that we will be replacing with a branch in the
413413 // Patchee Section.
414 write32le(Buf, read32le(Patchee->Data.begin() + PatcheeOffset));
414 write32le(Buf, read32le(Patchee->data().begin() + PatcheeOffset));
415415
416416 // Apply any relocation transferred from the original PatcheeSection.
417417 // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc
......@@ -451,7 +451,7 @@ void AArch64Err843419Patcher::init() {
451451 continue;
452452 if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))
453453 continue;
454 if (auto *Sec = dyn_cast<InputSection>(Def->Section))
454 if (auto *Sec = dyn_cast_or_null<InputSection>(Def->Section))
455455 if (Sec->Flags & SHF_EXECINSTR)
456456 SectionMap[Sec].push_back(Def);
457457 }
......@@ -487,7 +487,8 @@ void AArch64Err843419Patcher::insertPatches(
487487 InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
488488 uint64_t ISLimit;
489489 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
492493 // Set the OutSecOff of patches to the place where we want to insert them.
493494 // We use a similar strategy to Thunk placement. Place patches roughly
......@@ -498,12 +499,12 @@ void AArch64Err843419Patcher::insertPatches(
498499 ISLimit = IS->OutSecOff + IS->getSize();
499500 if (ISLimit > PatchUpperBound) {
500501 while (PatchIt != PatchEnd) {
501 if ((*PatchIt)->getLDSTAddr() >= PrevISLimit)
502 if ((*PatchIt)->getLDSTAddr() - OutSecAddr >= PrevISLimit)
502503 break;
503504 (*PatchIt)->OutSecOff = PrevISLimit;
504505 ++PatchIt;
505506 }
506 PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
507 PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
507508 }
508509 PrevISLimit = ISLimit;
509510 }
......@@ -538,20 +539,24 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
538539 InputSection *IS,
539540 std::vector<Patch843419Section *> &Patches) {
540541 // 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.
542543 // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this
543544 // instance of the erratum on a previous patch and altered the relocation. We
544545 // have nothing more to do.
545 // Case 2: A load/store register (unsigned immediate) class relocation. There
546 // 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
546550 // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and
547551 // they are both absolute. We need to add the same relocation to the patch,
548552 // and replace the relocation with a R_AARCH_JUMP26 branch relocation.
549 // Case 3: No relocation. We must create a new R_AARCH64_JUMP26 branch
553 // Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
550554 // relocation at the offset.
551555 auto RelIt = std::find_if(
552556 IS->Relocations.begin(), IS->Relocations.end(),
553557 [=](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))
555560 return;
556561
557562 log("detected cortex-a53-843419 erratum sequence starting at " +
......@@ -598,7 +603,7 @@ AArch64Err843419Patcher::patchInputSectionDescription(
598603 auto DataSym = std::next(CodeSym);
599604 uint64_t Off = (*CodeSym)->Value;
600605 uint64_t Limit =
601 (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value;
606 (DataSym == MapSyms.end()) ? IS->data().size() : (*DataSym)->Value;
602607
603608 while (Off < Limit) {
604609 uint64_t StartAddr = IS->getVA(Off);
deps/lld/ELF/Arch/AArch64.cpp+21-16
......@@ -41,6 +41,7 @@ public:
4141 int32_t Index, unsigned RelOff) const override;
4242 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
4343 uint64_t BranchAddr, const Symbol &S) const override;
44 uint32_t getThunkSectionSpacing() const override;
4445 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
4546 bool usesOnlyLowPageBits(RelType Type) const override;
4647 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
......@@ -57,6 +58,7 @@ AArch64::AArch64() {
5758 RelativeRel = R_AARCH64_RELATIVE;
5859 IRelativeRel = R_AARCH64_IRELATIVE;
5960 GotRel = R_AARCH64_GLOB_DAT;
61 NoneRel = R_AARCH64_NONE;
6062 PltRel = R_AARCH64_JUMP_SLOT;
6163 TlsDescRel = R_AARCH64_TLSDESC;
6264 TlsGotRel = R_AARCH64_TLS_TPREL64;
......@@ -66,22 +68,18 @@ AArch64::AArch64() {
6668 PltHeaderSize = 32;
6769 DefaultMaxPageSize = 65536;
6870
69 // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
70 // 1 of the tls structures and the tcb size is 16.
71 TcbSize = 16;
72 NeedsThunks = true;
71 // Align to the 2 MiB page size (known as a superpage or huge page).
72 // FreeBSD automatically promotes 2 MiB-aligned allocations.
73 DefaultImageBase = 0x200000;
7374
74 // See comment in Arch/ARM.cpp for a more detailed explanation of
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;
75 NeedsThunks = true;
7876}
7977
8078RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
8179 const uint8_t *Loc) const {
8280 switch (Type) {
8381 case R_AARCH64_TLSDESC_ADR_PAGE21:
84 return R_TLSDESC_PAGE;
82 return R_AARCH64_TLSDESC_PAGE;
8583 case R_AARCH64_TLSDESC_LD64_LO12:
8684 case R_AARCH64_TLSDESC_ADD_LO12:
8785 return R_TLSDESC;
......@@ -107,13 +105,13 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
107105 case R_AARCH64_LD_PREL_LO19:
108106 return R_PC;
109107 case R_AARCH64_ADR_PREL_PG_HI21:
110 return R_PAGE_PC;
108 return R_AARCH64_PAGE_PC;
111109 case R_AARCH64_LD64_GOT_LO12_NC:
112110 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
113111 return R_GOT;
114112 case R_AARCH64_ADR_GOT_PAGE:
115113 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
116 return R_GOT_PAGE_PC;
114 return R_AARCH64_GOT_PAGE_PC;
117115 case R_AARCH64_NONE:
118116 return R_NONE;
119117 default:
......@@ -125,7 +123,7 @@ RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
125123 RelExpr Expr) const {
126124 if (Expr == R_RELAX_TLS_GD_TO_IE) {
127125 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;
129127 return R_RELAX_TLS_GD_TO_IE_ABS;
130128 }
131129 return Expr;
......@@ -156,7 +154,7 @@ RelType AArch64::getDynRel(RelType Type) const {
156154}
157155
158156void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
159 write64le(Buf, InX::Plt->getVA());
157 write64le(Buf, In.Plt->getVA());
160158}
161159
162160void AArch64::writePltHeader(uint8_t *Buf) const {
......@@ -172,8 +170,8 @@ void AArch64::writePltHeader(uint8_t *Buf) const {
172170 };
173171 memcpy(Buf, PltData, sizeof(PltData));
174172
175 uint64_t Got = InX::GotPlt->getVA();
176 uint64_t Plt = InX::Plt->getVA();
173 uint64_t Got = In.GotPlt->getVA();
174 uint64_t Plt = In.Plt->getVA();
177175 relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
178176 getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
179177 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,
208206 return !inBranchRange(Type, BranchAddr, Dst);
209207}
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
211216bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
212217 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
213218 return true;
......@@ -338,7 +343,7 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
338343 or32le(Loc, (Val & 0xFFFC) << 3);
339344 break;
340345 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
341 checkInt(Loc, Val, 24, Type);
346 checkUInt(Loc, Val, 24, Type);
342347 or32AArch64Imm(Loc, Val >> 12);
343348 break;
344349 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
deps/lld/ELF/Arch/AMDGPU.cpp+1
......@@ -35,6 +35,7 @@ public:
3535AMDGPU::AMDGPU() {
3636 RelativeRel = R_AMDGPU_RELATIVE64;
3737 GotRel = R_AMDGPU_ABS64;
38 NoneRel = R_AMDGPU_NONE;
3839 GotEntrySize = 8;
3940}
4041
deps/lld/ELF/Arch/ARM.cpp+76-48
......@@ -40,6 +40,7 @@ public:
4040 void addPltHeaderSymbols(InputSection &ISD) const override;
4141 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
4242 uint64_t BranchAddr, const Symbol &S) const override;
43 uint32_t getThunkSectionSpacing() const override;
4344 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
4445 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
4546};
......@@ -50,6 +51,7 @@ ARM::ARM() {
5051 RelativeRel = R_ARM_RELATIVE;
5152 IRelativeRel = R_ARM_IRELATIVE;
5253 GotRel = R_ARM_GLOB_DAT;
54 NoneRel = R_ARM_NONE;
5355 PltRel = R_ARM_JUMP_SLOT;
5456 TlsGotRel = R_ARM_TLS_TPOFF32;
5557 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
......@@ -59,41 +61,8 @@ ARM::ARM() {
5961 GotPltEntrySize = 4;
6062 PltEntrySize = 16;
6163 PltHeaderSize = 32;
62 TrapInstr = 0xd4d4d4d4;
63 // ARM uses Variant 1 TLS
64 TcbSize = 8;
64 TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
6565 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;
9766}
9867
9968uint32_t ARM::calcEFlags() const {
......@@ -165,6 +134,12 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
165134 return R_NONE;
166135 case R_ARM_TLS_LE32:
167136 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;
168143 default:
169144 return R_ABS;
170145 }
......@@ -177,7 +152,7 @@ RelType ARM::getDynRel(RelType Type) const {
177152}
178153
179154void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
180 write32le(Buf, InX::Plt->getVA());
155 write32le(Buf, In.Plt->getVA());
181156}
182157
183158void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
......@@ -198,8 +173,8 @@ static void writePltHeaderLong(uint8_t *Buf) {
198173 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
199174 0xd4, 0xd4, 0xd4, 0xd4};
200175 memcpy(Buf, PltData, sizeof(PltData));
201 uint64_t GotPlt = InX::GotPlt->getVA();
202 uint64_t L1 = InX::Plt->getVA() + 8;
176 uint64_t GotPlt = In.GotPlt->getVA();
177 uint64_t L1 = In.Plt->getVA() + 8;
203178 write32le(Buf + 16, GotPlt - L1 - 8);
204179}
205180
......@@ -217,7 +192,7 @@ void ARM::writePltHeader(uint8_t *Buf) const {
217192 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
218193 };
219194
220 uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4;
195 uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
221196 if (!llvm::isUInt<27>(Offset)) {
222197 // We cannot encode the Offset, use the long form.
223198 writePltHeaderLong(Buf);
......@@ -227,10 +202,10 @@ void ARM::writePltHeader(uint8_t *Buf) const {
227202 write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
228203 write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
229204 write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
230 write32le(Buf + 16, TrapInstr); // Pad to 32-byte boundary
231 write32le(Buf + 20, TrapInstr);
232 write32le(Buf + 24, TrapInstr);
233 write32le(Buf + 28, TrapInstr);
205 memcpy(Buf + 16, TrapInstr.data(), 4); // Pad to 32-byte boundary
206 memcpy(Buf + 20, TrapInstr.data(), 4);
207 memcpy(Buf + 24, TrapInstr.data(), 4);
208 memcpy(Buf + 28, TrapInstr.data(), 4);
234209}
235210
236211void ARM::addPltHeaderSymbols(InputSection &IS) const {
......@@ -279,7 +254,7 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
279254 write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
280255 write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
281256 write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
282 write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary
257 memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary
283258}
284259
285260void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
......@@ -324,6 +299,40 @@ bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
324299 return false;
325300}
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
327336bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
328337 uint64_t Range;
329338 uint64_t InstrSize;
......@@ -342,7 +351,7 @@ bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
342351 break;
343352 case R_ARM_THM_JUMP24:
344353 case R_ARM_THM_CALL:
345 Range = 0x1000000;
354 Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
346355 InstrSize = 2;
347356 break;
348357 default:
......@@ -447,11 +456,23 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
447456 }
448457 // Bit 12 is 0 for BLX, 1 for BL
449458 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 }
450472 // Fall through as rest of encoding is the same as B.W
451473 LLVM_FALLTHROUGH;
452474 case R_ARM_THM_JUMP24:
453475 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
454 // FIXME: Use of I1 and I2 require v6T2ops
455476 checkInt(Loc, Val, 25, Type);
456477 write16le(Loc,
457478 0xf000 | // opcode
......@@ -470,14 +491,12 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
470491 break;
471492 case R_ARM_MOVT_ABS:
472493 case R_ARM_MOVT_PREL:
473 checkInt(Loc, Val, 32, Type);
474494 write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
475495 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
476496 break;
477497 case R_ARM_THM_MOVT_ABS:
478498 case R_ARM_THM_MOVT_PREL:
479499 // Encoding T1: A = imm4:i:imm3:imm8
480 checkInt(Loc, Val, 32, Type);
481500 write16le(Loc,
482501 0xf2c0 | // opcode
483502 ((Val >> 17) & 0x0400) | // i
......@@ -542,10 +561,19 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
542561 ((Lo & 0x07ff) << 1)); // imm11:0
543562 }
544563 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;
545574 case R_ARM_THM_JUMP24: {
546575 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
547576 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
548 // FIXME: I1 and I2 require v6T2ops
549577 uint16_t Hi = read16le(Buf);
550578 uint16_t Lo = read16le(Buf + 2);
551579 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
deps/lld/ELF/Arch/AVR.cpp+3
......@@ -43,12 +43,15 @@ using namespace lld::elf;
4343namespace {
4444class AVR final : public TargetInfo {
4545public:
46 AVR();
4647 RelExpr getRelExpr(RelType Type, const Symbol &S,
4748 const uint8_t *Loc) const override;
4849 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
4950};
5051} // namespace
5152
53AVR::AVR() { NoneRel = R_AVR_NONE; }
54
5255RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,
5356 const uint8_t *Loc) const {
5457 return R_ABS;
deps/lld/ELF/Arch/Hexagon.cpp+192-3
......@@ -9,6 +9,7 @@
99
1010#include "InputFiles.h"
1111#include "Symbols.h"
12#include "SyntheticSections.h"
1213#include "Target.h"
1314#include "lld/Common/ErrorHandler.h"
1415#include "llvm/BinaryFormat/ELF.h"
......@@ -25,15 +26,48 @@ using namespace lld::elf;
2526namespace {
2627class Hexagon final : public TargetInfo {
2728public:
29 Hexagon();
2830 uint32_t calcEFlags() const override;
2931 RelExpr getRelExpr(RelType Type, const Symbol &S,
3032 const uint8_t *Loc) const override;
3133 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;
3237};
3338} // namespace
3439
35// Support V60 only at the moment.
36uint32_t Hexagon::calcEFlags() const { return 0x60; }
40Hexagon::Hexagon() {
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
3872static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
3973 uint32_t Result = 0;
......@@ -53,29 +87,143 @@ static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
5387RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
5488 const uint8_t *Loc) const {
5589 switch (Type) {
90 case R_HEX_B9_PCREL:
91 case R_HEX_B9_PCREL_X:
92 case R_HEX_B13_PCREL:
5693 case R_HEX_B15_PCREL:
5794 case R_HEX_B15_PCREL_X:
95 case R_HEX_6_PCREL_X:
96 case R_HEX_32_PCREL:
97 return R_PC;
5898 case R_HEX_B22_PCREL:
99 case R_HEX_PLT_B22_PCREL:
59100 case R_HEX_B22_PCREL_X:
60101 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;
62107 default:
63108 return R_ABS;
64109 }
65110}
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
67180static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
68181
69182void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
70183 switch (Type) {
71184 case R_HEX_NONE:
72185 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;
73203 case R_HEX_12_X:
74204 or32le(Loc, applyMask(0x000007e0, Val));
75205 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;
76214 case R_HEX_32_6_X:
215 case R_HEX_GOT_32_6_X:
77216 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
78217 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;
79227 case R_HEX_B15_PCREL:
80228 or32le(Loc, applyMask(0x00df20fe, Val >> 2));
81229 break;
......@@ -83,6 +231,7 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
83231 or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));
84232 break;
85233 case R_HEX_B22_PCREL:
234 case R_HEX_PLT_B22_PCREL:
86235 or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
87236 break;
88237 case R_HEX_B22_PCREL_X:
......@@ -91,12 +240,52 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
91240 case R_HEX_B32_PCREL_X:
92241 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
93242 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;
94249 default:
95250 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
96251 break;
97252 }
98253}
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
100289TargetInfo *elf::getHexagonTargetInfo() {
101290 static Hexagon Target;
102291 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() {
5353 PltEntrySize = 16;
5454 PltHeaderSize = 32;
5555 CopyRel = R_MIPS_COPY;
56 NoneRel = R_MIPS_NONE;
5657 PltRel = R_MIPS_JUMP_SLOT;
5758 NeedsThunks = true;
58 TrapInstr = 0xefefefef;
59
60 // Set `sigrie 1` as a trap instruction.
61 write32(TrapInstr.data(), 0x04170001);
5962
6063 if (ELFT::Is64Bits) {
6164 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
......@@ -185,7 +188,7 @@ template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
185188
186189template <class ELFT>
187190void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
188 uint64_t VA = InX::Plt->getVA();
191 uint64_t VA = In.Plt->getVA();
189192 if (isMicroMips())
190193 VA |= 1;
191194 write32<ELFT::TargetEndianness>(Buf, VA);
......@@ -239,8 +242,8 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
239242template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
240243 const endianness E = ELFT::TargetEndianness;
241244 if (isMicroMips()) {
242 uint64_t GotPlt = InX::GotPlt->getVA();
243 uint64_t Plt = InX::Plt->getVA();
245 uint64_t GotPlt = In.GotPlt->getVA();
246 uint64_t Plt = In.Plt->getVA();
244247 // Overwrite trap instructions written by Writer::writeTrapInstr.
245248 memset(Buf, 0, PltHeaderSize);
246249
......@@ -292,7 +295,7 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
292295 write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
293296 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
294297
295 uint64_t GotPlt = InX::GotPlt->getVA();
298 uint64_t GotPlt = In.GotPlt->getVA();
296299 writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
297300 writeValue<E>(Buf + 4, GotPlt, 16, 0);
298301 writeValue<E>(Buf + 8, GotPlt, 16, 0);
deps/lld/ELF/Arch/PPC.cpp+5
......@@ -29,6 +29,7 @@ public:
2929} // namespace
3030
3131PPC::PPC() {
32 NoneRel = R_PPC_NONE;
3233 GotBaseSymOff = 0x8000;
3334 GotBaseSymInGotPlt = false;
3435}
......@@ -36,6 +37,7 @@ PPC::PPC() {
3637RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
3738 const uint8_t *Loc) const {
3839 switch (Type) {
40 case R_PPC_REL14:
3941 case R_PPC_REL24:
4042 case R_PPC_REL32:
4143 return R_PC;
......@@ -61,6 +63,9 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
6163 case R_PPC_REL32:
6264 write32be(Loc, Val);
6365 break;
66 case R_PPC_REL14:
67 write32be(Loc, read32be(Loc) | (Val & 0xFFFC));
68 break;
6469 case R_PPC_PLTREL24:
6570 case R_PPC_REL24:
6671 write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));
deps/lld/ELF/Arch/PPC64.cpp+436-37
......@@ -23,12 +23,49 @@ using namespace lld::elf;
2323static uint64_t PPC64TocOffset = 0x8000;
2424static 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
2663uint64_t elf::getPPC64TocBase() {
2764 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
2865 // TOC starts where the first of these sections starts. We always create a
2966 // .got when we see a relocation that uses it, so for us the start is always
3067 // the .got.
31 uint64_t TocVA = InX::Got->getVA();
68 uint64_t TocVA = In.Got->getVA();
3269
3370 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
3471 // thus permitting a full 64 Kbytes segment. Note that the glibc startup
......@@ -37,6 +74,31 @@ uint64_t elf::getPPC64TocBase() {
3774 return TocVA + PPC64TocOffset;
3875}
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
40102namespace {
41103class PPC64 final : public TargetInfo {
42104public:
......@@ -51,11 +113,16 @@ public:
51113 void writeGotHeader(uint8_t *Buf) const override;
52114 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
53115 uint64_t BranchAddr, const Symbol &S) const override;
116 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
54117 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
55118 RelExpr Expr) const override;
56119 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
57120 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
58121 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;
59126};
60127} // namespace
61128
......@@ -71,8 +138,64 @@ static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; }
71138static uint16_t highest(uint64_t V) { return V >> 48; }
72139static 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
74196PPC64::PPC64() {
75197 GotRel = R_PPC64_GLOB_DAT;
198 NoneRel = R_PPC64_NONE;
76199 PltRel = R_PPC64_JMP_SLOT;
77200 RelativeRel = R_PPC64_RELATIVE;
78201 IRelativeRel = R_PPC64_IRELATIVE;
......@@ -85,14 +208,14 @@ PPC64::PPC64() {
85208 GotPltHeaderEntriesNum = 2;
86209 PltHeaderSize = 60;
87210 NeedsThunks = true;
88 TcbSize = 8;
89 TlsTpOffset = 0x7000;
90211
91212 TlsModuleIndexRel = R_PPC64_DTPMOD64;
92213 TlsOffsetRel = R_PPC64_DTPREL64;
93214
94215 TlsGotRel = R_PPC64_TPREL64;
95216
217 NeedsMoreStackNonSplit = false;
218
96219 // We need 64K pages (at least under glibc/Linux, the loader won't
97220 // set different permissions on a finer granularity than that).
98221 DefaultMaxPageSize = 65536;
......@@ -107,8 +230,7 @@ PPC64::PPC64() {
107230 // use 0x10000000 as the starting address.
108231 DefaultImageBase = 0x10000000;
109232
110 TrapInstr =
111 (Config->IsLE == sys::IsLittleEndianHost) ? 0x7fe00008 : 0x0800e07f;
233 write32(TrapInstr.data(), 0x7fe00008);
112234}
113235
114236static uint32_t getEFlags(InputFile *File) {
......@@ -146,27 +268,29 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
146268 // bl __tls_get_addr(x@tlsgd) into nop
147269 // nop into addi r3, r3, x@tprel@l
148270
149 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
150
151271 switch (Type) {
152272 case R_PPC64_GOT_TLSGD16_HA:
153 write32(Loc - EndianOffset, 0x60000000); // nop
273 writeInstrFromHalf16(Loc, 0x60000000); // nop
154274 break;
275 case R_PPC64_GOT_TLSGD16:
155276 case R_PPC64_GOT_TLSGD16_LO:
156 write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13
277 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
157278 relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
158279 break;
159280 case R_PPC64_TLSGD:
160281 write32(Loc, 0x60000000); // nop
161282 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);
163288 break;
164289 default:
165290 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
166291 }
167292}
168293
169
170294void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
171295 // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
172296 // 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 {
183307 // bl __tls_get_addr(x@tlsgd) into nop
184308 // nop into addi r3, r3, 4096
185309
186 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
187310 switch (Type) {
188311 case R_PPC64_GOT_TLSLD16_HA:
189 write32(Loc - EndianOffset, 0x60000000); // nop
312 writeInstrFromHalf16(Loc, 0x60000000); // nop
190313 break;
191314 case R_PPC64_GOT_TLSLD16_LO:
192 write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13, 0
315 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
193316 break;
194317 case R_PPC64_TLSLD:
195318 write32(Loc, 0x60000000); // nop
......@@ -212,9 +335,90 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
212335 }
213336}
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
215412RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
216413 const uint8_t *Loc) const {
217414 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;
218422 case R_PPC64_TOC16:
219423 case R_PPC64_TOC16_DS:
220424 case R_PPC64_TOC16_HA:
......@@ -224,6 +428,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
224428 return R_GOTREL;
225429 case R_PPC64_TOC:
226430 return R_PPC_TOC;
431 case R_PPC64_REL14:
227432 case R_PPC64_REL24:
228433 return R_PPC_CALL_PLT;
229434 case R_PPC64_REL16_LO:
......@@ -279,7 +484,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
279484 case R_PPC64_TLSLD:
280485 return R_TLSLD_HINT;
281486 case R_PPC64_TLS:
282 return R_HINT;
487 return R_TLSIE_HINT;
283488 default:
284489 return R_ABS;
285490 }
......@@ -308,16 +513,16 @@ void PPC64::writePltHeader(uint8_t *Buf) const {
308513 // The 'bcl' instruction will set the link register to the address of the
309514 // following instruction ('mflr r11'). Here we store the offset from that
310515 // 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);
312517 write64(Buf + 52, GotPltOffset);
313518}
314519
315520void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
316521 uint64_t PltEntryAddr, int32_t Index,
317522 unsigned RelOff) const {
318 int32_t Offset = PltHeaderSize + Index * PltEntrySize;
319 // bl __glink_PLTresolve
320 write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
523 int32_t Offset = PltHeaderSize + Index * PltEntrySize;
524 // bl __glink_PLTresolve
525 write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
321526}
322527
323528static 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
329534 switch (Type) {
330535 // TOC biased relocation.
536 case R_PPC64_GOT16:
331537 case R_PPC64_GOT_TLSGD16:
332538 case R_PPC64_GOT_TLSLD16:
333539 case R_PPC64_TOC16:
334540 return {R_PPC64_ADDR16, TocBiasedVal};
541 case R_PPC64_GOT16_DS:
335542 case R_PPC64_TOC16_DS:
336543 case R_PPC64_GOT_TPREL16_DS:
337544 case R_PPC64_GOT_DTPREL16_DS:
338545 return {R_PPC64_ADDR16_DS, TocBiasedVal};
546 case R_PPC64_GOT16_HA:
339547 case R_PPC64_GOT_TLSGD16_HA:
340548 case R_PPC64_GOT_TLSLD16_HA:
341549 case R_PPC64_GOT_TPREL16_HA:
342550 case R_PPC64_GOT_DTPREL16_HA:
343551 case R_PPC64_TOC16_HA:
344552 return {R_PPC64_ADDR16_HA, TocBiasedVal};
553 case R_PPC64_GOT16_HI:
345554 case R_PPC64_GOT_TLSGD16_HI:
346555 case R_PPC64_GOT_TLSLD16_HI:
347556 case R_PPC64_GOT_TPREL16_HI:
348557 case R_PPC64_GOT_DTPREL16_HI:
349558 case R_PPC64_TOC16_HI:
350559 return {R_PPC64_ADDR16_HI, TocBiasedVal};
560 case R_PPC64_GOT16_LO:
351561 case R_PPC64_GOT_TLSGD16_LO:
352562 case R_PPC64_GOT_TLSLD16_LO:
353563 case R_PPC64_TOC16_LO:
354564 return {R_PPC64_ADDR16_LO, TocBiasedVal};
565 case R_PPC64_GOT16_LO_DS:
355566 case R_PPC64_TOC16_LO_DS:
356567 case R_PPC64_GOT_TPREL16_LO_DS:
357568 case R_PPC64_GOT_DTPREL16_LO_DS:
......@@ -386,9 +597,27 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
386597 }
387598}
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
389613void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
390 // For a TOC-relative relocation, proceed in terms of the corresponding
391 // ADDR16 relocation type.
614 // We need to save the original relocation type to use in diagnostics, and
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.
392621 std::tie(Type, Val) = toAddr16Rel(Type, Val);
393622
394623 switch (Type) {
......@@ -401,18 +630,25 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
401630 }
402631 case R_PPC64_ADDR16:
403632 case R_PPC64_TPREL16:
404 checkInt(Loc, Val, 16, Type);
633 checkInt(Loc, Val, 16, OriginalType);
405634 write16(Loc, Val);
406635 break;
407636 case R_PPC64_ADDR16_DS:
408 case R_PPC64_TPREL16_DS:
409 checkInt(Loc, Val, 16, Type);
410 write16(Loc, (read16(Loc) & 3) | (Val & ~3));
411 break;
637 case R_PPC64_TPREL16_DS: {
638 checkInt(Loc, Val, 16, OriginalType);
639 // DQ-form instructions use bits 28-31 as part of the instruction encoding
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;
412645 case R_PPC64_ADDR16_HA:
413646 case R_PPC64_REL16_HA:
414647 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));
416652 break;
417653 case R_PPC64_ADDR16_HI:
418654 case R_PPC64_REL16_HI:
......@@ -438,12 +674,40 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
438674 case R_PPC64_ADDR16_LO:
439675 case R_PPC64_REL16_LO:
440676 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 }
441689 write16(Loc, lo(Val));
442690 break;
443691 case R_PPC64_ADDR16_LO_DS:
444 case R_PPC64_TPREL16_LO_DS:
445 write16(Loc, (read16(Loc) & 3) | (lo(Val) & ~3));
446 break;
692 case R_PPC64_TPREL16_LO_DS: {
693 // DQ-form instructions use bits 28-31 as part of the instruction encoding
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;
447711 case R_PPC64_ADDR32:
448712 case R_PPC64_REL32:
449713 checkInt(Loc, Val, 32, Type);
......@@ -454,9 +718,17 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
454718 case R_PPC64_TOC:
455719 write64(Loc, Val);
456720 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 }
457728 case R_PPC64_REL24: {
458729 uint32_t Mask = 0x03FFFFFC;
459 checkInt(Loc, Val, 24, Type);
730 checkInt(Loc, Val, 26, Type);
731 checkAlignment(Loc, Val, 4, Type);
460732 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
461733 break;
462734 }
......@@ -470,9 +742,30 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
470742
471743bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
472744 uint64_t BranchAddr, const Symbol &S) const {
473 // If a function is in the plt it needs to be called through
474 // a call stub.
475 return Type == R_PPC64_REL24 && S.isInPlt();
745 if (Type != R_PPC64_REL14 && Type != R_PPC64_REL24)
746 return false;
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");
476769}
477770
478771RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
......@@ -511,9 +804,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
511804 case R_PPC64_GOT_TLSGD16_LO: {
512805 // Relax from addi r3, rA, sym@got@tlsgd@l to
513806 // ld r3, sym@got@tprel@l(rA)
514 uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
515 uint32_t InputRegister = (read32(Loc - EndianOffset) & (0x1f << 16));
516 write32(Loc - EndianOffset, 0xE8600000 | InputRegister);
807 uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16));
808 writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister);
517809 relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
518810 return;
519811 }
......@@ -526,6 +818,113 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
526818 }
527819}
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
529928TargetInfo *elf::getPPC64TargetInfo() {
530929 static PPC64 Target;
531930 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:
3535SPARCV9::SPARCV9() {
3636 CopyRel = R_SPARC_COPY;
3737 GotRel = R_SPARC_GLOB_DAT;
38 NoneRel = R_SPARC_NONE;
3839 PltRel = R_SPARC_JMP_SLOT;
3940 RelativeRel = R_SPARC_RELATIVE;
4041 GotEntrySize = 8;
deps/lld/ELF/Arch/X86.cpp+15-10
......@@ -48,6 +48,7 @@ public:
4848X86::X86() {
4949 CopyRel = R_386_COPY;
5050 GotRel = R_386_GLOB_DAT;
51 NoneRel = R_386_NONE;
5152 PltRel = R_386_JUMP_SLOT;
5253 IRelativeRel = R_386_IRELATIVE;
5354 RelativeRel = R_386_RELATIVE;
......@@ -59,7 +60,11 @@ X86::X86() {
5960 PltEntrySize = 16;
6061 PltHeaderSize = 16;
6162 TlsGdRelaxSkip = 2;
62 TrapInstr = 0xcccccccc; // 0xcc = INT3
63 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;
6368}
6469
6570static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
......@@ -152,7 +157,7 @@ RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,
152157}
153158
154159void X86::writeGotPltHeader(uint8_t *Buf) const {
155 write32le(Buf, InX::Dynamic->getVA());
160 write32le(Buf, In.Dynamic->getVA());
156161}
157162
158163void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
......@@ -183,8 +188,8 @@ void X86::writePltHeader(uint8_t *Buf) const {
183188 };
184189 memcpy(Buf, V, sizeof(V));
185190
186 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
187 uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
191 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
192 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
188193 write32le(Buf + 2, GotPlt + 4);
189194 write32le(Buf + 8, GotPlt + 8);
190195 return;
......@@ -196,7 +201,7 @@ void X86::writePltHeader(uint8_t *Buf) const {
196201 0x90, 0x90, 0x90, 0x90, // nop
197202 };
198203 memcpy(Buf, PltData, sizeof(PltData));
199 uint32_t GotPlt = InX::GotPlt->getVA();
204 uint32_t GotPlt = In.GotPlt->getVA();
200205 write32le(Buf + 2, GotPlt + 4);
201206 write32le(Buf + 8, GotPlt + 8);
202207}
......@@ -213,7 +218,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
213218
214219 if (Config->Pic) {
215220 // jmp *foo@GOT(%ebx)
216 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
221 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
217222 Buf[1] = 0xa3;
218223 write32le(Buf + 2, GotPltEntryAddr - Ebx);
219224 } else {
......@@ -447,8 +452,8 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const {
447452 };
448453 memcpy(Buf, Insn, sizeof(Insn));
449454
450 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
451 uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
455 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
456 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
452457 write32le(Buf + 2, GotPlt + 4);
453458 write32le(Buf + 9, GotPlt + 8);
454459}
......@@ -467,7 +472,7 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
467472 };
468473 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();
471476 unsigned Off = getPltEntryOffset(Index);
472477 write32le(Buf + 3, GotPltEntryAddr - Ebx);
473478 write32le(Buf + 8, -Off - 12 + 32);
......@@ -506,7 +511,7 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
506511 };
507512 memcpy(Buf, Insn, sizeof(Insn));
508513
509 uint32_t GotPlt = InX::GotPlt->getVA();
514 uint32_t GotPlt = In.GotPlt->getVA();
510515 write32le(Buf + 2, GotPlt + 4);
511516 write32le(Buf + 8, GotPlt + 8);
512517}
deps/lld/ELF/Arch/X86_64.cpp+59-32
......@@ -43,8 +43,8 @@ public:
4343 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
4444 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
4545 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
46 bool adjustPrologueForCrossSplitStack(uint8_t *Loc,
47 uint8_t *End) const override;
46 bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
47 uint8_t StOther) const override;
4848
4949private:
5050 void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
......@@ -55,6 +55,7 @@ private:
5555template <class ELFT> X86_64<ELFT>::X86_64() {
5656 CopyRel = R_X86_64_COPY;
5757 GotRel = R_X86_64_GLOB_DAT;
58 NoneRel = R_X86_64_NONE;
5859 PltRel = R_X86_64_JUMP_SLOT;
5960 RelativeRel = R_X86_64_RELATIVE;
6061 IRelativeRel = R_X86_64_IRELATIVE;
......@@ -66,7 +67,7 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
6667 PltEntrySize = 16;
6768 PltHeaderSize = 16;
6869 TlsGdRelaxSkip = 2;
69 TrapInstr = 0xcccccccc; // 0xcc = INT3
70 TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
7071
7172 // Align to the large page size (known as a superpage or huge page).
7273 // FreeBSD automatically promotes large, superpage-aligned allocations.
......@@ -124,7 +125,7 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
124125 // required, but it is documented in the psabi and the glibc dynamic linker
125126 // seems to use it (note that this is relevant for linking ld.so, not any
126127 // other program).
127 write64le(Buf, InX::Dynamic->getVA());
128 write64le(Buf, In.Dynamic->getVA());
128129}
129130
130131template <class ELFT>
......@@ -140,8 +141,8 @@ template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {
140141 0x0f, 0x1f, 0x40, 0x00, // nop
141142 };
142143 memcpy(Buf, PltData, sizeof(PltData));
143 uint64_t GotPlt = InX::GotPlt->getVA();
144 uint64_t Plt = InX::Plt->getVA();
144 uint64_t GotPlt = In.GotPlt->getVA();
145 uint64_t Plt = In.Plt->getVA();
145146 write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
146147 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
147148}
......@@ -263,15 +264,6 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
263264template <class ELFT>
264265void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
265266 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
275267 if (Type == R_X86_64_DTPOFF64) {
276268 write64le(Loc, Val);
277269 return;
......@@ -286,7 +278,37 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
286278 0x66, // .byte 0x66
287279 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
288280 };
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");
290312}
291313
292314template <class ELFT>
......@@ -481,23 +503,27 @@ namespace {
481503// B) Or a load of a stack pointer offset with an lea to r10 or r11.
482504template <>
483505bool 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
485511 // Replace "cmp %fs:0x70,%rsp" and subsequent branch
486512 // 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) {
488514 memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
489515 return true;
490516 }
491517
492 // Adjust "lea -0x200(%rsp),%r10" to lea "-0x4200(%rsp),%r10"
493 if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x94\x24\x00\xfe\xff", 7) == 0) {
494 memcpy(Loc, "\x4c\x8d\x94\x24\x00\xbe\xff", 7);
495 return true;
496 }
497
498 // Adjust "lea -0x200(%rsp),%r11" to lea "-0x4200(%rsp),%r11"
499 if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x9c\x24\x00\xfe\xff", 7) == 0) {
500 memcpy(Loc, "\x4c\x8d\x9c\x24\x00\xbe\xff", 7);
518 // Adjust "lea X(%rsp),%rYY" to lea "(X - 0x4000)(%rsp),%rYY" where rYY could
519 // be r10 or r11. The lea instruction feeds a subsequent compare which checks
520 // if there is X available stack space. Making X larger effectively reserves
521 // that much additional space. The stack grows downward so subtract the value.
522 if (memcmp(Loc, "\x4c\x8d\x94\x24", 4) == 0 ||
523 memcmp(Loc, "\x4c\x8d\x9c\x24", 4) == 0) {
524 // The offset bytes are encoded four bytes after the start of the
525 // instruction.
526 write32le(Loc + 4, read32le(Loc + 4) - 0x4000);
501527 return true;
502528 }
503529 return false;
......@@ -505,7 +531,8 @@ bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
505531
506532template <>
507533bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
508 uint8_t *End) const {
534 uint8_t *End,
535 uint8_t StOther) const {
509536 llvm_unreachable("Target doesn't support split stacks.");
510537}
511538
......@@ -566,8 +593,8 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
566593 };
567594 memcpy(Buf, Insn, sizeof(Insn));
568595
569 uint64_t GotPlt = InX::GotPlt->getVA();
570 uint64_t Plt = InX::Plt->getVA();
596 uint64_t GotPlt = In.GotPlt->getVA();
597 uint64_t Plt = In.Plt->getVA();
571598 write32le(Buf + 2, GotPlt - Plt - 6 + 8);
572599 write32le(Buf + 9, GotPlt - Plt - 13 + 16);
573600}
......@@ -586,7 +613,7 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
586613 };
587614 memcpy(Buf, Insn, sizeof(Insn));
588615
589 uint64_t Off = TargetInfo::getPltEntryOffset(Index);
616 uint64_t Off = getPltEntryOffset(Index);
590617
591618 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
592619 write32le(Buf + 8, -Off - 12 + 32);
......@@ -629,7 +656,7 @@ void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
629656 memcpy(Buf, Insn, sizeof(Insn));
630657
631658 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
632 write32le(Buf + 8, -TargetInfo::getPltEntryOffset(Index) - 12);
659 write32le(Buf + 8, -getPltEntryOffset(Index) - 12);
633660}
634661
635662template <class ELFT> static TargetInfo *getTargetInfo() {
deps/lld/ELF/CMakeLists.txt+3-1
......@@ -15,17 +15,19 @@ add_lld_library(lldELF
1515 Arch/Hexagon.cpp
1616 Arch/Mips.cpp
1717 Arch/MipsArchTree.cpp
18 Arch/MSP430.cpp
1819 Arch/PPC.cpp
1920 Arch/PPC64.cpp
21 Arch/RISCV.cpp
2022 Arch/SPARCV9.cpp
2123 Arch/X86.cpp
2224 Arch/X86_64.cpp
2325 CallGraphSort.cpp
26 DWARF.cpp
2427 Driver.cpp
2528 DriverUtils.cpp
2629 EhFrame.cpp
2730 Filesystem.cpp
28 GdbIndex.cpp
2931 ICF.cpp
3032 InputFiles.cpp
3133 InputSection.cpp
deps/lld/ELF/CallGraphSort.cpp+21-30
......@@ -57,10 +57,7 @@ struct Edge {
5757};
5858
5959struct Cluster {
60 Cluster(int Sec, size_t S) {
61 Sections.push_back(Sec);
62 Size = S;
63 }
60 Cluster(int Sec, size_t S) : Sections{Sec}, Size(S) {}
6461
6562 double getDensity() const {
6663 if (Size == 0)
......@@ -72,7 +69,7 @@ struct Cluster {
7269 size_t Size = 0;
7370 uint64_t Weight = 0;
7471 uint64_t InitialWeight = 0;
75 std::vector<Edge> Preds;
72 Edge BestPred = {-1, 0};
7673};
7774
7875class CallGraphSort {
......@@ -96,12 +93,14 @@ constexpr int MAX_DENSITY_DEGRADATION = 8;
9693constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024;
9794} // end anonymous namespace
9895
96typedef std::pair<const InputSectionBase *, const InputSectionBase *>
97 SectionPair;
98
9999// Take the edge list in Config->CallGraphProfile, resolve symbol names to
100100// Symbols, and generate a graph between InputSections with the provided
101101// weights.
102102CallGraphSort::CallGraphSort() {
103 llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
104 uint64_t> &Profile = Config->CallGraphProfile;
103 MapVector<SectionPair, uint64_t> &Profile = Config->CallGraphProfile;
105104 DenseMap<const InputSectionBase *, int> SecToCluster;
106105
107106 auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {
......@@ -114,7 +113,7 @@ CallGraphSort::CallGraphSort() {
114113 };
115114
116115 // Create the graph.
117 for (const auto &C : Profile) {
116 for (std::pair<SectionPair, uint64_t> &C : Profile) {
118117 const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);
119118 const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);
120119 uint64_t Weight = C.second;
......@@ -136,8 +135,12 @@ CallGraphSort::CallGraphSort() {
136135 if (From == To)
137136 continue;
138137
139 // Add an edge
140 Clusters[To].Preds.push_back({From, Weight});
138 // Remember the best edge.
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 }
141144 }
142145 for (Cluster &C : Clusters)
143146 C.InitialWeight = C.Weight;
......@@ -146,9 +149,7 @@ CallGraphSort::CallGraphSort() {
146149// It's bad to merge clusters which would degrade the density too much.
147150static bool isNewDensityBad(Cluster &A, Cluster &B) {
148151 double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);
149 if (NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION)
150 return true;
151 return false;
152 return NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION;
152153}
153154
154155static void mergeClusters(Cluster &Into, Cluster &From) {
......@@ -167,9 +168,9 @@ void CallGraphSort::groupClusters() {
167168 std::vector<int> SortedSecs(Clusters.size());
168169 std::vector<Cluster *> SecToCluster(Clusters.size());
169170
170 for (int SI = 0, SE = Clusters.size(); SI != SE; ++SI) {
171 SortedSecs[SI] = SI;
172 SecToCluster[SI] = &Clusters[SI];
171 for (size_t I = 0; I < Clusters.size(); ++I) {
172 SortedSecs[I] = I;
173 SecToCluster[I] = &Clusters[I];
173174 }
174175
175176 std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
......@@ -181,21 +182,11 @@ void CallGraphSort::groupClusters() {
181182 // been merged into another cluster yet.
182183 Cluster &C = Clusters[SI];
183184
184 int BestPred = -1;
185 uint64_t BestWeight = 0;
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)
185 // Don't consider merging if the edge is unlikely.
186 if (C.BestPred.From == -1 || C.BestPred.Weight * 10 <= C.InitialWeight)
196187 continue;
197188
198 Cluster *PredC = SecToCluster[BestPred];
189 Cluster *PredC = SecToCluster[C.BestPred.From];
199190 if (PredC == &C)
200191 continue;
201192
......@@ -229,7 +220,7 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
229220 groupClusters();
230221
231222 // Generate order.
232 llvm::DenseMap<const InputSectionBase *, int> OrderMap;
223 DenseMap<const InputSectionBase *, int> OrderMap;
233224 ssize_t CurOrder = 1;
234225
235226 for (const Cluster &C : Clusters)
deps/lld/ELF/Config.h+11-1
......@@ -47,7 +47,7 @@ enum class ICFLevel { None, Safe, All };
4747enum class StripPolicy { None, All, Debug };
4848
4949// For --unresolved-symbols.
50enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll };
50enum class UnresolvedPolicy { ReportError, Warn, Ignore };
5151
5252// For --orphan-handling.
5353enum class OrphanHandlingPolicy { Place, Warn, Error };
......@@ -127,6 +127,7 @@ struct Configuration {
127127 bool AsNeeded = false;
128128 bool Bsymbolic;
129129 bool BsymbolicFunctions;
130 bool CallGraphProfileSort;
130131 bool CheckSections;
131132 bool CompressDebugSections;
132133 bool Cref;
......@@ -134,11 +135,13 @@ struct Configuration {
134135 bool Demangle = true;
135136 bool DisableVerify;
136137 bool EhFrameHdr;
138 bool EmitLLVM;
137139 bool EmitRelocs;
138140 bool EnableNewDtags;
139141 bool ExecuteOnly;
140142 bool ExportDynamic;
141143 bool FixCortexA53Errata843419;
144 bool FormatBinary = false;
142145 bool GcSections;
143146 bool GdbIndex;
144147 bool GnuHash = false;
......@@ -156,6 +159,7 @@ struct Configuration {
156159 bool OFormatBinary;
157160 bool Omagic;
158161 bool OptRemarksWithHotness;
162 bool PicThunk;
159163 bool Pie;
160164 bool PrintGcSections;
161165 bool PrintIcfSections;
......@@ -170,19 +174,24 @@ struct Configuration {
170174 bool Trace;
171175 bool ThinLTOEmitImportsFiles;
172176 bool ThinLTOIndexOnly;
177 bool TocOptimize;
173178 bool UndefinedVersion;
174179 bool UseAndroidRelrTags = false;
175180 bool WarnBackrefs;
176181 bool WarnCommon;
182 bool WarnIfuncTextrel;
177183 bool WarnMissingEntry;
178184 bool WarnSymbolOrdering;
179185 bool WriteAddends;
180186 bool ZCombreloc;
181187 bool ZCopyreloc;
182188 bool ZExecstack;
189 bool ZGlobal;
183190 bool ZHazardplt;
184191 bool ZInitfirst;
192 bool ZInterpose;
185193 bool ZKeepTextSectionPrefix;
194 bool ZNodefaultlib;
186195 bool ZNodelete;
187196 bool ZNodlopen;
188197 bool ZNow;
......@@ -212,6 +221,7 @@ struct Configuration {
212221 unsigned LTOO;
213222 unsigned Optimize;
214223 unsigned ThinLTOJobs;
224 int32_t SplitStackAdjustSize;
215225
216226 // The following config options do not directly correspond to any
217227 // 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;
6363using namespace llvm::ELF;
6464using namespace llvm::object;
6565using namespace llvm::sys;
66using namespace llvm::support;
6667
6768using namespace lld;
6869using namespace lld::elf;
......@@ -74,7 +75,7 @@ static void setConfigs(opt::InputArgList &Args);
7475
7576bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
7677 raw_ostream &Error) {
77 errorHandler().LogName = sys::path::filename(Args[0]);
78 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
7879 errorHandler().ErrorLimitExceededMsg =
7980 "too many errors emitted, stopping now (use "
8081 "-error-limit=0 to see all errors)";
......@@ -84,7 +85,6 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
8485
8586 InputSections.clear();
8687 OutputSections.clear();
87 Tar = nullptr;
8888 BinaryFiles.clear();
8989 BitcodeFiles.clear();
9090 ObjectFiles.clear();
......@@ -94,6 +94,10 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
9494 Driver = make<LinkerDriver>();
9595 Script = make<LinkerScript>();
9696 Symtab = make<SymbolTable>();
97
98 Tar = nullptr;
99 memset(&In, 0, sizeof(In));
100
97101 Config->ProgName = Args[0];
98102
99103 Driver->main(Args);
......@@ -125,9 +129,11 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
125129 .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
126130 .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
127131 .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
132 .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
128133 .Case("elf32ppc", {ELF32BEKind, EM_PPC})
129134 .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
130135 .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
136 .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
131137 .Case("elf64ppc", {ELF64BEKind, EM_PPC64})
132138 .Case("elf64lppc", {ELF64LEKind, EM_PPC64})
133139 .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
......@@ -183,7 +189,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
183189 return;
184190 MemoryBufferRef MBRef = *Buffer;
185191
186 if (InBinary) {
192 if (Config->FormatBinary) {
187193 Files.push_back(make<BinaryFile>(MBRef));
188194 return;
189195 }
......@@ -218,7 +224,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
218224 return;
219225 }
220226 case file_magic::elf_shared_object:
221 if (Config->Relocatable) {
227 if (Config->Static || Config->Relocatable) {
222228 error("attempted static link of dynamic object " + Path);
223229 return;
224230 }
......@@ -269,14 +275,17 @@ static void initLLVM() {
269275
270276// Some command line options or some combinations of them are not allowed.
271277// This function checks for such errors.
272static void checkOptions(opt::InputArgList &Args) {
278static void checkOptions() {
273279 // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
274280 // table which is a relatively new feature.
275281 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
278284 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
281290 if (Config->Pie && Config->Shared)
282291 error("-shared and -pie may not be used together");
......@@ -336,12 +345,13 @@ static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
336345 return Default;
337346}
338347
339static bool isKnown(StringRef S) {
348static bool isKnownZFlag(StringRef S) {
340349 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" ||
342352 S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
343 S == "nocombreloc" || S == "nocopyreloc" || S == "nodelete" ||
344 S == "nodlopen" || S == "noexecstack" ||
353 S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
354 S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
345355 S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
346356 S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
347357 S == "rodynamic" || S == "text" || S == "wxneeded" ||
......@@ -351,7 +361,7 @@ static bool isKnown(StringRef S) {
351361// Report an error for an unknown -z option.
352362static void checkZOptions(opt::InputArgList &Args) {
353363 for (auto *Arg : Args.filtered(OPT_z))
354 if (!isKnown(Arg->getValue()))
364 if (!isKnownZFlag(Arg->getValue()))
355365 error("unknown -z value: " + StringRef(Arg->getValue()));
356366}
357367
......@@ -386,31 +396,30 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
386396 if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
387397 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
396399 if (const char *Path = getReproduceOption(Args)) {
397400 // Note that --reproduce is a debug option so you can ignore it
398401 // if you are trying to understand the whole picture of the code.
399402 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
400403 TarWriter::create(Path, path::stem(Path));
401404 if (ErrOrWriter) {
402 Tar = ErrOrWriter->get();
405 Tar = std::move(*ErrOrWriter);
403406 Tar->append("response.txt", createResponseFile(Args));
404407 Tar->append("version.txt", getLLDVersion() + "\n");
405 make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
406408 } else {
407 error(Twine("--reproduce: failed to open ") + Path + ": " +
408 toString(ErrOrWriter.takeError()));
409 error("--reproduce: " + toString(ErrOrWriter.takeError()));
409410 }
410411 }
411412
412413 readConfigs(Args);
413414 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
414423 initLLVM();
415424 createFiles(Args);
416425 if (errorCount())
......@@ -418,7 +427,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
418427
419428 inferMachineType();
420429 setConfigs(Args);
421 checkOptions(Args);
430 checkOptions();
422431 if (errorCount())
423432 return;
424433
......@@ -448,9 +457,6 @@ static std::string getRpath(opt::InputArgList &Args) {
448457// Determines what we should do if there are remaining unresolved
449458// symbols after the name resolution.
450459static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
451 if (Args.hasArg(OPT_relocatable))
452 return UnresolvedPolicy::IgnoreAll;
453
454460 UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
455461 OPT_warn_unresolved_symbols, true)
456462 ? UnresolvedPolicy::ReportError
......@@ -497,14 +503,11 @@ static Target2Policy getTarget2(opt::InputArgList &Args) {
497503}
498504
499505static bool isOutputFormatBinary(opt::InputArgList &Args) {
500 if (auto *Arg = Args.getLastArg(OPT_oformat)) {
501 StringRef S = Arg->getValue();
502 if (S == "binary")
503 return true;
504 if (S.startswith("elf"))
505 return false;
506 StringRef S = Args.getLastArgValue(OPT_oformat, "elf");
507 if (S == "binary")
508 return true;
509 if (!S.startswith("elf"))
506510 error("unknown --oformat value: " + S);
507 }
508511 return false;
509512}
510513
......@@ -645,38 +648,56 @@ static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {
645648
646649static void readCallGraph(MemoryBufferRef MB) {
647650 // Build a map from symbol name to section
648 DenseMap<StringRef, const Symbol *> SymbolNameToSymbol;
651 DenseMap<StringRef, Symbol *> Map;
649652 for (InputFile *File : ObjectFiles)
650653 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)) {
654671 SmallVector<StringRef, 3> Fields;
655 L.split(Fields, ' ');
672 Line.split(Fields, ' ');
656673 uint64_t Count;
657 if (Fields.size() != 3 || !to_integer(Fields[2], Count))
658 fatal(MB.getBufferIdentifier() + ": parse error");
659 const Symbol *FromSym = SymbolNameToSymbol.lookup(Fields[0]);
660 const Symbol *ToSym = SymbolNameToSymbol.lookup(Fields[1]);
661 if (Config->WarnSymbolOrdering) {
662 if (!FromSym)
663 warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[0]);
664 if (!ToSym)
665 warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[1]);
674
675 if (Fields.size() != 3 || !to_integer(Fields[2], Count)) {
676 error(MB.getBufferIdentifier() + ": parse error");
677 return;
678 }
679
680 if (InputSectionBase *From = FindSection(Fields[0]))
681 if (InputSectionBase *To = FindSection(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;
666700 }
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;
680701 }
681702}
682703
......@@ -753,7 +774,10 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
753774 Config->DynamicLinker = getDynamicLinker(Args);
754775 Config->EhFrameHdr =
755776 Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
777 Config->EmitLLVM = Args.hasArg(OPT_plugin_opt_emit_llvm, false);
756778 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);
757781 Config->EnableNewDtags =
758782 Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
759783 Config->Entry = Args.getLastArgValue(OPT_entry);
......@@ -808,6 +832,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
808832 Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
809833 Config->SoName = Args.getLastArgValue(OPT_soname);
810834 Config->SortSection = getSortSection(Args);
835 Config->SplitStackAdjustSize = args::getInteger(Args, OPT_split_stack_adjust_size, 16384);
811836 Config->Strip = getStrip(Args);
812837 Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
813838 Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
......@@ -837,15 +862,20 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
837862 Config->WarnBackrefs =
838863 Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
839864 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);
840867 Config->WarnSymbolOrdering =
841868 Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
842869 Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
843870 Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
844871 Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
872 Config->ZGlobal = hasZOption(Args, "global");
845873 Config->ZHazardplt = hasZOption(Args, "hazardplt");
846874 Config->ZInitfirst = hasZOption(Args, "initfirst");
875 Config->ZInterpose = hasZOption(Args, "interpose");
847876 Config->ZKeepTextSectionPrefix = getZFlag(
848877 Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
878 Config->ZNodefaultlib = hasZOption(Args, "nodefaultlib");
849879 Config->ZNodelete = hasZOption(Args, "nodelete");
850880 Config->ZNodlopen = hasZOption(Args, "nodlopen");
851881 Config->ZNow = getZFlag(Args, "now", "lazy", false);
......@@ -876,6 +906,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
876906 if (Config->ThinLTOJobs == 0)
877907 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
879912 // Parse ELF{32,64}{LE,BE} and CPU type.
880913 if (auto *Arg = Args.getLastArg(OPT_m)) {
881914 StringRef S = Arg->getValue();
......@@ -964,22 +997,18 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
964997// This function initialize such members. See Config.h for the details
965998// of these values.
966999static void setConfigs(opt::InputArgList &Args) {
967 ELFKind Kind = Config->EKind;
968 uint16_t Machine = Config->EMachine;
1000 ELFKind K = Config->EKind;
1001 uint16_t M = Config->EMachine;
9691002
9701003 Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
971 Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind);
972 Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind);
973 Config->Endianness =
974 Config->IsLE ? support::endianness::little : support::endianness::big;
975 Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS);
1004 Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind);
1005 Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind);
1006 Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
1007 Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
9761008 Config->Pic = Config->Pie || Config->Shared;
1009 Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
9771010 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
9831012 // ELF defines two different ways to store relocation addends as shown below:
9841013 //
9851014 // Rel: Addends are stored to the location where relocations are applied.
......@@ -993,8 +1022,9 @@ static void setConfigs(opt::InputArgList &Args) {
9931022 // You cannot choose which one, Rel or Rela, you want to use. Instead each
9941023 // ABI defines which one you need to use. The following expression expresses
9951024 // that.
996 Config->IsRela =
997 (Config->Is64 || IsX32 || Machine == EM_PPC) && Machine != EM_MIPS;
1025 Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
1026 M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
1027 M == EM_X86_64;
9981028
9991029 // If the output uses REL relocations we must store the dynamic relocation
10001030 // addends to the output sections. We also store addends for RELA relocations
......@@ -1004,10 +1034,13 @@ static void setConfigs(opt::InputArgList &Args) {
10041034 Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
10051035 OPT_no_apply_dynamic_relocs, false) ||
10061036 !Config->IsRela;
1037
1038 Config->TocOptimize =
1039 Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
10071040}
10081041
10091042// Returns a value of "-format" option.
1010static bool getBinaryOption(StringRef S) {
1043static bool isFormatBinary(StringRef S) {
10111044 if (S == "binary")
10121045 return true;
10131046 if (S == "elf" || S == "default")
......@@ -1034,7 +1067,10 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
10341067 StringRef From;
10351068 StringRef To;
10361069 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"));
10381074 break;
10391075 }
10401076 case OPT_script:
......@@ -1049,7 +1085,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
10491085 Config->AsNeeded = true;
10501086 break;
10511087 case OPT_format:
1052 InBinary = getBinaryOption(Arg->getValue());
1088 Config->FormatBinary = isFormatBinary(Arg->getValue());
10531089 break;
10541090 case OPT_no_as_needed:
10551091 Config->AsNeeded = false;
......@@ -1220,33 +1256,34 @@ template <class ELFT> static void handleUndefined(StringRef Name) {
12201256 Symtab->fetchLazy<ELFT>(Sym);
12211257}
12221258
1223template <class ELFT> static bool shouldDemote(Symbol &Sym) {
1224 // If all references to a DSO happen to be weak, the DSO is not added to
1225 // DT_NEEDED. If that happens, we need to eliminate shared symbols created
1226 // from the DSO. Otherwise, they become dangling references that point to a
1227 // non-existent DSO.
1228 if (auto *S = dyn_cast<SharedSymbol>(&Sym))
1229 return !S->getFile<ELFT>().IsNeeded;
1230
1231 // We are done processing archives, so lazy symbols that were used but not
1232 // found can be converted to undefined. We could also just delete the other
1233 // lazy symbols, but that seems to be more work than it is worth.
1234 return Sym.isLazy() && Sym.IsUsedInRegularObj;
1259template <class ELFT> static void handleLibcall(StringRef Name) {
1260 Symbol *Sym = Symtab->find(Name);
1261 if (!Sym || !Sym->isLazy())
1262 return;
1263
1264 MemoryBufferRef MB;
1265 if (auto *LO = dyn_cast<LazyObject>(Sym))
1266 MB = LO->File->MB;
1267 else
1268 MB = cast<LazyArchive>(Sym)->getMemberBuffer();
1269
1270 if (isBitcode(MB))
1271 Symtab->fetchLazy<ELFT>(Sym);
12351272}
12361273
1237// Some files, such as .so or files between -{start,end}-lib may be removed
1238// after their symbols are added to the symbol table. If that happens, we
1239// need to remove symbols that refer files that no longer exist, so that
1240// they won't appear in the symbol table of the output file.
1241//
1242// We remove symbols by demoting them to undefined symbol.
1243template <class ELFT> static void demoteSymbols() {
1274// If all references to a DSO happen to be weak, the DSO is not added
1275// to DT_NEEDED. If that happens, we need to eliminate shared symbols
1276// created from the DSO. Otherwise, they become dangling references
1277// that point to a non-existent DSO.
1278template <class ELFT> static void demoteSharedSymbols() {
12441279 for (Symbol *Sym : Symtab->getSymbols()) {
1245 if (shouldDemote<ELFT>(*Sym)) {
1246 bool Used = Sym->Used;
1247 replaceSymbol<Undefined>(Sym, nullptr, Sym->getName(), Sym->Binding,
1248 Sym->StOther, Sym->Type);
1249 Sym->Used = Used;
1280 if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
1281 if (!S->getFile<ELFT>().IsNeeded) {
1282 bool Used = S->Used;
1283 replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
1284 S->Type);
1285 S->Used = Used;
1286 }
12501287 }
12511288 }
12521289}
......@@ -1315,6 +1352,85 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
13151352 }
13161353}
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
13181434static const char *LibcallRoutineNames[] = {
13191435#define HANDLE_LIBCALL(code, name) name,
13201436#include "llvm/IR/RuntimeLibcalls.def"
......@@ -1325,6 +1441,8 @@ static const char *LibcallRoutineNames[] = {
13251441// all linker scripts have already been parsed.
13261442template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
13271443 Target = getTarget();
1444 InX<ELFT>::VerSym = nullptr;
1445 InX<ELFT>::VerNeed = nullptr;
13281446
13291447 Config->MaxPageSize = getMaxPageSize(Args);
13301448 Config->ImageBase = getImageBase(Args);
......@@ -1380,8 +1498,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
13801498
13811499 // Some symbols (such as __ehdr_start) are defined lazily only when there
13821500 // are undefined symbols for them, so we add these to trigger that logic.
1383 for (StringRef Sym : Script->ReferencedSymbols)
1384 Symtab->addUndefined<ELFT>(Sym);
1501 for (StringRef Name : Script->ReferencedSymbols)
1502 addUndefined<ELFT>(Name);
13851503
13861504 // Handle the `--undefined <sym>` options.
13871505 for (StringRef S : Config->Undefined)
......@@ -1396,11 +1514,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
13961514 // in a bitcode file in an archive member, we need to arrange to use LTO to
13971515 // compile those archive members by adding them to the link beforehand.
13981516 //
1399 // With this the symbol table should be complete. After this, no new names
1400 // except a few linker-synthesized ones will be added to the symbol table.
1517 // However, adding all libcall symbols to the link can have undesired
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.
14011528 if (!BitcodeFiles.empty())
14021529 for (const char *S : LibcallRoutineNames)
1403 handleUndefined<ELFT>(S);
1530 handleLibcall<ELFT>(S);
14041531
14051532 // Return if there were name resolution errors.
14061533 if (errorCount())
......@@ -1424,6 +1551,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
14241551 Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
14251552 Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
14261553
1554 // Create wrapped symbols for -wrap option.
1555 std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
1556
14271557 // We need to create some reserved symbols such as _end. Create them.
14281558 if (!Config->Relocatable)
14291559 addReservedSymbols();
......@@ -1436,12 +1566,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
14361566 if (!Config->Relocatable)
14371567 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
14431569 // Do link-time optimization if given files are LLVM bitcode files.
14441570 // 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.
14451574 Symtab->addCombinedLTOObject<ELFT>();
14461575 if (errorCount())
14471576 return;
......@@ -1452,8 +1581,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
14521581 if (Config->ThinLTOIndexOnly)
14531582 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
14551590 // Apply symbol renames for -wrap.
1456 Symtab->applySymbolWrap();
1591 if (!Wrapped.empty())
1592 wrapSymbols<ELFT>(Wrapped);
14571593
14581594 // Now that we have a complete list of input files.
14591595 // Beyond this point, no new files are added.
......@@ -1481,27 +1617,19 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
14811617 // supports them.
14821618 if (Config->ARMHasBlx == false)
14831619 warn("lld uses blx instruction, no object with architecture supporting "
1484 "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.");
1620 "feature detected");
14911621 }
14921622
14931623 // This adds a .comment section containing a version string. We have to add it
1494 // before decompressAndMergeSections because the .comment section is a
1495 // mergeable section.
1624 // before mergeSections because the .comment section is a mergeable section.
14961625 if (!Config->Relocatable)
14971626 InputSections.push_back(createCommentSection());
14981627
14991628 // Do size optimizations: garbage collection, merging of SHF_MERGE sections
15001629 // and identical code folding.
1501 decompressSections();
15021630 splitSections<ELFT>();
15031631 markLive<ELFT>();
1504 demoteSymbols<ELFT>();
1632 demoteSharedSymbols<ELFT>();
15051633 mergeSections();
15061634 if (Config->ICF != ICFLevel::None) {
15071635 findKeepUniqueSections<ELFT>(Args);
......@@ -1509,9 +1637,12 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
15091637 }
15101638
15111639 // Read the callgraph now that we know what was gced or icfed
1512 if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
1513 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
1514 readCallGraph(*Buffer);
1640 if (Config->CallGraphProfileSort) {
1641 if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
1642 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
1643 readCallGraph(*Buffer);
1644 readCallGraphsFromObjectFiles<ELFT>();
1645 }
15151646
15161647 // Write the result to the file.
15171648 writeResult<ELFT>();
deps/lld/ELF/Driver.h-3
......@@ -42,9 +42,6 @@ private:
4242 // True if we are in --start-lib and --end-lib.
4343 bool InLib = false;
4444
45 // True if we are in -format=binary and -format=elf.
46 bool InBinary = false;
47
4845 std::vector<InputFile *> Files;
4946};
5047
deps/lld/ELF/DriverUtils.cpp+3-2
......@@ -139,8 +139,9 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
139139}
140140
141141void elf::printHelp() {
142 ELFOptTable().PrintHelp(outs(), Config->ProgName.data(), "lld",
143 false /*ShowHidden*/, true /*ShowAllAliases*/);
142 ELFOptTable().PrintHelp(
143 outs(), (Config->ProgName + " [options] file...").str().c_str(), "lld",
144 false /*ShowHidden*/, true /*ShowAllAliases*/);
144145 outs() << "\n";
145146
146147 // 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:
4444private:
4545 template <class P> void failOn(const P *Loc, const Twine &Msg) {
4646 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()));
4848 }
4949
5050 uint8_t readByte();
......@@ -59,7 +59,7 @@ private:
5959}
6060
6161size_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();
6363}
6464
6565// .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,
252252
253253 auto *DA = dyn_cast<Defined>(&SA);
254254 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)
256259 return false;
257260
258261 // Relocations referring to absolute symbols are constant-equal if their
......@@ -298,7 +301,7 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
298301template <class ELFT>
299302bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
300303 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())
302305 return false;
303306
304307 // 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) {
420423 ++Cnt;
421424}
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
423442static void print(const Twine &S) {
424443 if (Config->PrintIcfSections)
425444 message(S);
......@@ -435,10 +454,18 @@ template <class ELFT> void ICF<ELFT>::run() {
435454
436455 // Initially, we use hash values to partition sections.
437456 parallelForEach(Sections, [&](InputSection *S) {
438 // Set MSB to 1 to avoid collisions with non-hash IDs.
439 S->Class[0] = xxHash64(S->Data) | (1U << 31);
457 S->Class[0] = xxHash64(S->data());
440458 });
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
442469 // From now on, sections in Sections vector are ordered so that sections
443470 // in the same equivalence class are consecutive in the vector.
444471 std::stable_sort(Sections.begin(), Sections.end(),
deps/lld/ELF/InputFiles.cpp+74-73
......@@ -46,7 +46,7 @@ std::vector<LazyObjFile *> elf::LazyObjFiles;
4646std::vector<InputFile *> elf::ObjectFiles;
4747std::vector<InputFile *> elf::SharedFiles;
4848
49TarWriter *elf::Tar;
49std::unique_ptr<TarWriter> elf::Tar;
5050
5151InputFile::InputFile(Kind K, MemoryBufferRef M)
5252 : MB(M), GroupId(NextGroupId), FileKind(K) {
......@@ -125,11 +125,7 @@ std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
125125
126126template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
127127 Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
128 const DWARFObject &Obj = Dwarf->getDWARFObj();
129 DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE,
130 Config->Wordsize);
131
132 for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units()) {
128 for (std::unique_ptr<DWARFUnit> &CU : Dwarf->compile_units()) {
133129 auto Report = [](Error Err) {
134130 handleAllErrors(std::move(Err),
135131 [](ErrorInfoBase &Info) { warn(Info.message()); });
......@@ -324,17 +320,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
324320 return Signature;
325321}
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
338323template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
339324 // On a regular link we don't merge sections if -O0 (default is -O1). This
340325 // sometimes makes the linker significantly faster, although the output will
......@@ -416,6 +401,11 @@ void ObjFile<ELFT>::initializeSections(
416401 continue;
417402 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
419409 // SHF_EXCLUDE'ed sections are discarded by the linker. However,
420410 // if -r is given, we'll let the final link discard such sections.
421411 // This is compatible with GNU.
......@@ -439,22 +429,34 @@ void ObjFile<ELFT>::initializeSections(
439429 case SHT_GROUP: {
440430 // De-duplicate section groups by their signatures.
441431 StringRef Signature = getShtGroupSignature(ObjSections, Sec);
442 bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
443432 this->Sections[I] = &InputSection::Discarded;
444433
445 // If it is a new section group, we want to keep group members.
446 // Group leader sections, which contain indices of group members, are
447 // discarded because they are useless beyond this point. The only
448 // exception is the -r option because in order to produce re-linkable
449 // object files, we want to pass through basically everything.
434
435 ArrayRef<Elf_Word> Entries =
436 CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
437 if (Entries.empty())
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;
450451 if (IsNew) {
451452 if (Config->Relocatable)
452453 this->Sections[I] = createInputSection(Sec);
453 continue;
454 continue;
454455 }
455456
457
456458 // Otherwise, discard group members.
457 for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
459 for (uint32_t SecIndex : Entries.slice(1)) {
458460 if (SecIndex >= Size)
459461 fatal(toString(this) +
460462 ": invalid section index in group: " + Twine(SecIndex));
......@@ -478,11 +480,13 @@ void ObjFile<ELFT>::initializeSections(
478480 // .ARM.exidx sections have a reverse dependency on the InputSection they
479481 // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
480482 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)
482487 fatal(toString(this) +
483488 ": invalid sh_link index: " + Twine(Sec.sh_link));
484489
485 InputSectionBase *LinkSec = this->Sections[Sec.sh_link];
486490 InputSection *IS = cast<InputSection>(this->Sections[I]);
487491 LinkSec->DependentSections.push_back(IS);
488492 if (!isa<InputSection>(LinkSec))
......@@ -598,7 +602,7 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
598602// as a given section.
599603static InputSection *toRegularSection(MergeInputSection *Sec) {
600604 return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
601 Sec->Data, Sec->Name);
605 Sec->data(), Sec->Name);
602606}
603607
604608template <class ELFT>
......@@ -618,9 +622,9 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
618622 // FIXME: Retain the first attribute section we see. The eglibc ARM
619623 // dynamic loaders require the presence of an attribute section for dlopen
620624 // to work. In a full implementation we would merge all attribute sections.
621 if (InX::ARMAttributes == nullptr) {
622 InX::ARMAttributes = make<InputSection>(*this, Sec, Name);
623 return InX::ARMAttributes;
625 if (In.ARMAttributes == nullptr) {
626 In.ARMAttributes = make<InputSection>(*this, Sec, Name);
627 return In.ARMAttributes;
624628 }
625629 return &InputSection::Discarded;
626630 }
......@@ -638,8 +642,16 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
638642 // This section contains relocation information.
639643 // If -r is given, we do not interpret or apply relocation
640644 // but just copy relocation sections to output.
641 if (Config->Relocatable)
642 return make<InputSection>(*this, Sec, Name);
645 if (Config->Relocatable) {
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
644656 if (Target->FirstRelocation)
645657 fatal(toString(this) +
......@@ -704,7 +716,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
704716 // for split stack will include a .note.GNU-split-stack section.
705717 if (Name == ".note.GNU-split-stack") {
706718 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");
708720 return &InputSection::Discarded;
709721 }
710722 this->SplitStack = true;
......@@ -724,7 +736,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
724736 // sections. Drop those sections to avoid duplicate symbol errors.
725737 // FIXME: This is glibc PR20543, we should remove this hack once that has been
726738 // 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")
728741 return &InputSection::Discarded;
729742
730743 // 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) {
806819 if (Sec == &InputSection::Discarded)
807820 return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
808821 /*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,
810823 this);
811824 }
812825}
......@@ -940,8 +953,7 @@ std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
940953 auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
941954 Verdef += CurVerdef->vd_next;
942955 unsigned VerdefIndex = CurVerdef->vd_ndx;
943 if (Verdefs.size() <= VerdefIndex)
944 Verdefs.resize(VerdefIndex + 1);
956 Verdefs.resize(VerdefIndex + 1);
945957 Verdefs[VerdefIndex] = CurVerdef;
946958 }
947959
......@@ -993,25 +1005,25 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
9931005 for (size_t I = 0; I < Syms.size(); ++I) {
9941006 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
10051008 // ELF spec requires that all local symbols precede weak or global
10061009 // symbols in each symbol table, and the index of first non-local symbol
10071010 // is stored to sh_info. If a local symbol appears after some non-local
10081011 // symbol, that's a violation of the spec.
1012 StringRef Name = CHECK(Sym.getName(this->StringTable), this);
10091013 if (Sym.getBinding() == STB_LOCAL) {
10101014 warn("found local symbol '" + Name +
10111015 "' in global part of symbol table in file " + toString(this));
10121016 continue;
10131017 }
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
10151027 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly
10161028 // assigns VER_NDX_LOCAL to this section global symbol. Here is a
10171029 // workaround for this bug.
......@@ -1054,6 +1066,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
10541066 switch (T.getArch()) {
10551067 case Triple::aarch64:
10561068 return EM_AARCH64;
1069 case Triple::amdgcn:
1070 case Triple::r600:
1071 return EM_AMDGPU;
10571072 case Triple::arm:
10581073 case Triple::thumb:
10591074 return EM_ARM;
......@@ -1064,9 +1079,12 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
10641079 case Triple::mips64:
10651080 case Triple::mips64el:
10661081 return EM_MIPS;
1082 case Triple::msp430:
1083 return EM_MSP430;
10671084 case Triple::ppc:
10681085 return EM_PPC;
10691086 case Triple::ppc64:
1087 case Triple::ppc64le:
10701088 return EM_PPC64;
10711089 case Triple::x86:
10721090 return T.isOSIAMCU() ? EM_IAMCU : EM_386;
......@@ -1178,7 +1196,7 @@ static ELFKind getELFKind(MemoryBufferRef MB) {
11781196}
11791197
11801198void BinaryFile::parse() {
1181 ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
1199 ArrayRef<uint8_t> Data = arrayRefFromStringRef(MB.getBuffer());
11821200 auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
11831201 8, Data, ".data");
11841202 Sections.push_back(Section);
......@@ -1192,11 +1210,11 @@ void BinaryFile::parse() {
11921210 if (!isAlnum(S[I]))
11931211 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,
11961214 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,
11981216 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,
12001218 Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
12011219}
12021220
......@@ -1262,25 +1280,11 @@ template <class ELFT> void LazyObjFile::parse() {
12621280 return;
12631281 }
12641282
1265 switch (getELFKind(this->MB)) {
1266 case ELF32LEKind:
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>();
1283 if (getELFKind(this->MB) != Config->EKind) {
1284 error("incompatible file: " + this->MB.getBufferIdentifier());
12771285 return;
1278 default:
1279 llvm_unreachable("getELFKind");
12801286 }
1281}
12821287
1283template <class ELFT> void LazyObjFile::addElfSymbols() {
12841288 ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
12851289 ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);
12861290
......@@ -1305,12 +1309,9 @@ std::string elf::replaceThinLTOSuffix(StringRef Path) {
13051309 StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
13061310 StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
13071311
1308 if (!Path.endswith(Suffix)) {
1309 error("-thinlto-object-suffix-replace=" + Suffix + ";" + Repl +
1310 " was given, but " + Path + " does not end with the suffix");
1311 return "";
1312 }
1313 return (Path.drop_back(Suffix.size()) + Repl).str();
1312 if (Path.consume_back(Suffix))
1313 return (Path + Repl).str();
1314 return Path;
13141315}
13151316
13161317template void ArchiveFile::parse<ELF32LE>();
deps/lld/ELF/InputFiles.h+8-5
......@@ -50,7 +50,7 @@ class Symbol;
5050
5151// If -reproduce option is given, all input files are written
5252// to this tar archive.
53extern llvm::TarWriter *Tar;
53extern std::unique_ptr<llvm::TarWriter> Tar;
5454
5555// Opens a given file.
5656llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
......@@ -86,7 +86,9 @@ public:
8686
8787 // Returns object file symbols. It is a runtime error to call this
8888 // function on files of other types.
89 ArrayRef<Symbol *> getSymbols() {
89 ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
90
91 std::vector<Symbol *> &getMutableSymbols() {
9092 assert(FileKind == BinaryKind || FileKind == ObjKind ||
9193 FileKind == BitcodeKind);
9294 return Symbols;
......@@ -169,10 +171,10 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
169171 typedef typename ELFT::Sym Elf_Sym;
170172 typedef typename ELFT::Shdr Elf_Shdr;
171173 typedef typename ELFT::Word Elf_Word;
174 typedef typename ELFT::CGProfile Elf_CGProfile;
172175
173176 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
174177 const Elf_Shdr &Sec);
175 ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
176178
177179public:
178180 static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
......@@ -218,6 +220,9 @@ public:
218220 // Pointer to this input file's .llvm_addrsig section, if it has one.
219221 const Elf_Shdr *AddrsigSec = nullptr;
220222
223 // SHT_LLVM_CALL_GRAPH_PROFILE table
224 ArrayRef<Elf_CGProfile> CGProfile;
225
221226private:
222227 void
223228 initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
......@@ -272,8 +277,6 @@ public:
272277 bool AddedToLink = false;
273278
274279private:
275 template <class ELFT> void addElfSymbols();
276
277280 uint64_t OffsetInArchive;
278281};
279282
deps/lld/ELF/InputSection.cpp+271-188
......@@ -21,7 +21,6 @@
2121#include "Thunks.h"
2222#include "lld/Common/ErrorHandler.h"
2323#include "lld/Common/Memory.h"
24#include "llvm/Object/Decompressor.h"
2524#include "llvm/Support/Compiler.h"
2625#include "llvm/Support/Compression.h"
2726#include "llvm/Support/Endian.h"
......@@ -64,11 +63,11 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
6463 StringRef Name, Kind SectionKind)
6564 : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
6665 Link),
67 File(File), Data(Data) {
66 File(File), RawData(Data) {
6867 // In order to reduce memory allocation, we assume that mergeable
6968 // sections are smaller than 4 GiB, which is not an unreasonable
7069 // assumption as of 2017.
71 if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX)
70 if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
7271 error(toString(this) + ": section too large");
7372
7473 NumRelocations = 0;
......@@ -80,6 +79,17 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
8079 if (!isPowerOf2_64(V))
8180 fatal(toString(File) + ": section sh_addralign is not a power of 2");
8281 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 }
8393}
8494
8595// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
......@@ -128,13 +138,25 @@ InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
128138size_t InputSectionBase::getSize() const {
129139 if (auto *S = dyn_cast<SyntheticSection>(this))
130140 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);
133155}
134156
135157uint64_t InputSectionBase::getOffsetInFile() const {
136158 const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
137 const uint8_t *SecStart = Data.begin();
159 const uint8_t *SecStart = data().begin();
138160 return SecStart - FileStart;
139161}
140162
......@@ -180,34 +202,70 @@ OutputSection *SectionBase::getOutputSection() {
180202 return Sec ? Sec->getParent() : nullptr;
181203}
182204
183// Decompress section contents if required. Note that this function
184// is called from parallelForEach, so it must be thread-safe.
185void InputSectionBase::maybeDecompress() {
186 if (DecompressBuf)
187 return;
188 if (!(Flags & SHF_COMPRESSED) && !Name.startswith(".zdebug"))
189 return;
205// When a section is compressed, `RawData` consists with a header followed
206// by zlib-compressed data. This function parses a header to initialize
207// `UncompressedSize` member and remove the header from `RawData`.
208void InputSectionBase::parseCompressedHeader() {
209 typedef typename ELF64LE::Chdr Chdr64;
210 typedef typename ELF32LE::Chdr Chdr32;
190211
191 // Decompress a section.
192 Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data),
193 Config->IsLE, Config->Is64));
212 // Old-style header
213 if (Name.startswith(".zdebug")) {
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();
196 DecompressBuf.reset(new char[Size + Name.size()]());
197 if (Error E = Dec.decompress({DecompressBuf.get(), Size}))
198 fatal(toString(this) +
199 ": decompress failed: " + llvm::toString(std::move(E)));
220 if (RawData.size() < 8) {
221 error(toString(this) + ": corrupted compressed section header");
222 return;
223 }
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);
202235 Flags &= ~(uint64_t)SHF_COMPRESSED;
203236
204 // A section name may have been altered if compressed. If that's
205 // the case, restore the original name. (i.e. ".zdebug_" -> ".debug_")
206 if (Name.startswith(".zdebug")) {
207 DecompressBuf[Size] = '.';
208 memcpy(&DecompressBuf[Size + 1], Name.data() + 2, Name.size() - 2);
209 Name = StringRef(&DecompressBuf[Size], Name.size() - 1);
237 // New-style 64-bit header
238 if (Config->Is64) {
239 if (RawData.size() < sizeof(Chdr64)) {
240 error(toString(this) + ": corrupted compressed section");
241 return;
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;
210253 }
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));
211269}
212270
213271InputSection *InputSectionBase::getLinkOrderDep() const {
......@@ -230,14 +288,17 @@ Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
230288// Returns a source location string. Used to construct an error message.
231289template <class ELFT>
232290std::string InputSectionBase::getLocation(uint64_t Offset) {
291 std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
292
233293 // We don't have file for synthetic sections.
234294 if (getFile<ELFT>() == nullptr)
235 return (Config->OutputFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")")
295 return (Config->OutputFile + ":(" + SecAndOffset + ")")
236296 .str();
237297
238298 // First check if we can get desired values from debugging information.
239299 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
242303 // File->SourceFile contains STT_FILE symbol that contains a
243304 // source file name. If it's missing, we use an object file name.
......@@ -246,10 +307,10 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
246307 SrcFile = toString(File);
247308
248309 if (Defined *D = getEnclosingFunction<ELFT>(Offset))
249 return SrcFile + ":(function " + toString(*D) + ")";
310 return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
250311
251312 // If there's no symbol, print out the offset in the section.
252 return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
313 return (SrcFile + ":(" + SecAndOffset + ")");
253314}
254315
255316// This function is intended to be used for constructing an error message.
......@@ -259,9 +320,6 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
259320//
260321// Returns an empty string if there's no way to get line info.
261322std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
262 // Synthetic sections don't have input files.
263 if (!File)
264 return "";
265323 return File->getSrcMsg(Sym, *this, Offset);
266324}
267325
......@@ -275,9 +333,6 @@ std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
275333//
276334// path/to/foo.o:(function bar) in archive path/to/bar.a
277335std::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();
281336 std::string Filename = File->getName();
282337
283338 std::string Archive;
......@@ -362,7 +417,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
362417 // Output section VA is zero for -r, so r_offset is an offset within the
363418 // section, but for --emit-relocs it is an virtual address.
364419 P->r_offset = Sec->getVA(Rel.r_offset);
365 P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type,
420 P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
366421 Config->IsMips64EL);
367422
368423 if (Sym.Type == STT_SECTION) {
......@@ -380,14 +435,14 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
380435 error("STT_SECTION symbol should be defined");
381436 continue;
382437 }
383 SectionBase *Section = D->Section;
384 if (Section == &InputSection::Discarded) {
438 SectionBase *Section = D->Section->Repl;
439 if (!Section->Live) {
385440 P->setSymbolAndType(0, 0, false);
386441 continue;
387442 }
388443
389444 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;
391446 if (!RelTy::IsRela)
392447 Addend = Target->getImplicitAddend(BufLoc, Type);
393448
......@@ -487,6 +542,62 @@ static uint64_t getARMStaticBase(const Symbol &Sym) {
487542 return OS->PtLoad->FirstSec->Addr;
488543}
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
490601static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
491602 uint64_t P, const Symbol &Sym, RelExpr Expr) {
492603 switch (Expr) {
......@@ -501,38 +612,37 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
501612 case R_ARM_SBREL:
502613 return Sym.getVA(A) - getARMStaticBase(Sym);
503614 case R_GOT:
615 case R_GOT_PLT:
504616 case R_RELAX_TLS_GD_TO_IE_ABS:
505617 return Sym.getGotVA() + A;
506618 case R_GOTONLY_PC:
507 return InX::Got->getVA() + A - P;
619 return In.Got->getVA() + A - P;
508620 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();
510622 case R_GOTREL:
511 return Sym.getVA(A) - InX::Got->getVA();
623 return Sym.getVA(A) - In.Got->getVA();
512624 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();
514626 case R_GOT_FROM_END:
515627 case R_RELAX_TLS_GD_TO_IE_END:
516 return Sym.getGotOffset() + A - InX::Got->getSize();
628 return Sym.getGotOffset() + A - In.Got->getSize();
517629 case R_TLSLD_GOT_OFF:
518630 case R_GOT_OFF:
519631 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
520632 return Sym.getGotOffset() + A;
521 case R_GOT_PAGE_PC:
522 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
633 case R_AARCH64_GOT_PAGE_PC:
634 case R_AARCH64_GOT_PAGE_PC_PLT:
635 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
523636 return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
524637 case R_GOT_PC:
525638 case R_RELAX_TLS_GD_TO_IE:
526639 return Sym.getGotVA() + A - P;
527 case R_HINT:
528 case R_NONE:
529 case R_TLSDESC_CALL:
530 case R_TLSLD_HINT:
531 llvm_unreachable("cannot relocate hint relocs");
640 case R_HEXAGON_GOT:
641 return Sym.getGotVA() - In.GotPlt->getVA();
532642 case R_MIPS_GOTREL:
533 return Sym.getVA(A) - InX::MipsGot->getGp(File);
643 return Sym.getVA(A) - In.MipsGot->getGp(File);
534644 case R_MIPS_GOT_GP:
535 return InX::MipsGot->getGp(File) + A;
645 return In.MipsGot->getGp(File) + A;
536646 case R_MIPS_GOT_GP_PC: {
537647 // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
538648 // 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,
541651 // microMIPS variants of these relocations use slightly different
542652 // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
543653 // 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;
545655 if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
546656 V += 4;
547657 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,
552662 // If relocation against MIPS local symbol requires GOT entry, this entry
553663 // should be initialized by 'page address'. This address is high 16-bits
554664 // of sum the symbol's value and the addend.
555 return InX::MipsGot->getVA() +
556 InX::MipsGot->getPageEntryOffset(File, Sym, A) -
557 InX::MipsGot->getGp(File);
665 return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
666 In.MipsGot->getGp(File);
558667 case R_MIPS_GOT_OFF:
559668 case R_MIPS_GOT_OFF32:
560669 // In case of MIPS if a GOT relocation has non-zero addend this addend
561670 // should be applied to the GOT entry content not to the GOT entry offset.
562671 // That is why we use separate expression type.
563 return InX::MipsGot->getVA() +
564 InX::MipsGot->getSymEntryOffset(File, Sym, A) -
565 InX::MipsGot->getGp(File);
672 return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
673 In.MipsGot->getGp(File);
566674 case R_MIPS_TLSGD:
567 return InX::MipsGot->getVA() + InX::MipsGot->getGlobalDynOffset(File, Sym) -
568 InX::MipsGot->getGp(File);
675 return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
676 In.MipsGot->getGp(File);
569677 case R_MIPS_TLSLD:
570 return InX::MipsGot->getVA() + InX::MipsGot->getTlsIndexOffset(File) -
571 InX::MipsGot->getGp(File);
572 case R_PAGE_PC:
573 case R_PLT_PAGE_PC: {
574 uint64_t Dest;
575 if (Sym.isUndefWeak())
576 Dest = getAArch64Page(A);
577 else
578 Dest = getAArch64Page(Sym.getVA(A));
579 return Dest - getAArch64Page(P);
678 return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
679 In.MipsGot->getGp(File);
680 case R_AARCH64_PAGE_PC: {
681 uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
682 return getAArch64Page(Val) - getAArch64Page(P);
683 }
684 case R_AARCH64_PLT_PAGE_PC: {
685 uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getPltVA() + A;
686 return getAArch64Page(Val) - 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;
580693 }
581694 case R_PC: {
582695 uint64_t Dest;
......@@ -608,16 +721,12 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
608721 return 0;
609722
610723 // 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, the
612 // call should branch to the local entry point rather than the global entry
613 // point. Section 3.4.1 describes using the 3 most significant bits of the
614 // st_other field to find out how many instructions there are between the
615 // local and global entry point.
616 uint8_t StOther = (Sym.StOther >> 5) & 7;
617 if (StOther == 0 || StOther == 1)
618 return SymVA - P;
619
620 return SymVA - P + (1LL << StOther);
724 // point is used for calls where the caller and callee (may) have different
725 // TOC base pointers and r2 needs to be modified to hold the TOC base for
726 // the callee. For local calls the caller and callee share the same
727 // TOC base and so the TOC pointer initialization code should be skipped by
728 // branching to the local entry point.
729 return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
621730 }
622731 case R_PPC_TOC:
623732 return getPPC64TocBase() + A;
......@@ -634,48 +743,32 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
634743 // statically to zero.
635744 if (Sym.isTls() && Sym.isUndefWeak())
636745 return 0;
637
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;
746 return Sym.getVA(A) + getTlsTpOffset();
655747 case R_RELAX_TLS_GD_TO_LE_NEG:
656748 case R_NEG_TLS:
657749 return Out::TlsPhdr->p_memsz - Sym.getVA(A);
658750 case R_SIZE:
659751 return Sym.getSize() + A;
660752 case R_TLSDESC:
661 return InX::Got->getGlobalDynAddr(Sym) + A;
662 case R_TLSDESC_PAGE:
663 return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) -
753 return In.Got->getGlobalDynAddr(Sym) + A;
754 case R_AARCH64_TLSDESC_PAGE:
755 return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
664756 getAArch64Page(P);
665757 case R_TLSGD_GOT:
666 return InX::Got->getGlobalDynOffset(Sym) + A;
758 return In.Got->getGlobalDynOffset(Sym) + A;
667759 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();
669761 case R_TLSGD_PC:
670 return InX::Got->getGlobalDynAddr(Sym) + A - P;
762 return In.Got->getGlobalDynAddr(Sym) + A - P;
671763 case R_TLSLD_GOT_FROM_END:
672 return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
764 return In.Got->getTlsIndexOff() + A - In.Got->getSize();
673765 case R_TLSLD_GOT:
674 return InX::Got->getTlsIndexOff() + A;
766 return In.Got->getTlsIndexOff() + A;
675767 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");
677771 }
678 llvm_unreachable("Invalid expression");
679772}
680773
681774// This function applies relocations to sections without SHF_ALLOC bit.
......@@ -808,10 +901,10 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
808901 case R_RELAX_TLS_GD_TO_LE_NEG:
809902 Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
810903 break;
904 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
811905 case R_RELAX_TLS_GD_TO_IE:
812906 case R_RELAX_TLS_GD_TO_IE_ABS:
813907 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
814 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
815908 case R_RELAX_TLS_GD_TO_IE_END:
816909 Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
817910 break;
......@@ -848,16 +941,20 @@ static void switchMorestackCallsToMorestackNonSplit(
848941 // __morestack inside that function should be switched to
849942 // __morestack_non_split.
850943 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
852950 // Sort both collections to compare addresses efficiently.
853 llvm::sort(MorestackCalls.begin(), MorestackCalls.end(),
854 [](const Relocation *L, const Relocation *R) {
855 return L->Offset < R->Offset;
856 });
951 llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
952 return L->Offset < R->Offset;
953 });
857954 std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
858 llvm::sort(
859 Functions.begin(), Functions.end(),
860 [](const Defined *L, const Defined *R) { return L->Value < R->Value; });
955 llvm::sort(Functions, [](const Defined *L, const Defined *R) {
956 return L->Value < R->Value;
957 });
861958
862959 auto It = MorestackCalls.begin();
863960 for (Defined *F : Functions) {
......@@ -872,8 +969,8 @@ static void switchMorestackCallsToMorestackNonSplit(
872969 }
873970}
874971
875static bool enclosingPrologueAdjusted(uint64_t Offset,
876 const DenseSet<Defined *> &Prologues) {
972static bool enclosingPrologueAttempted(uint64_t Offset,
973 const DenseSet<Defined *> &Prologues) {
877974 for (Defined *F : Prologues)
878975 if (F->Value <= Offset && Offset < F->Value + F->Size)
879976 return true;
......@@ -889,7 +986,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
889986 uint8_t *End) {
890987 if (!getFile<ELFT>()->SplitStack)
891988 return;
892 DenseSet<Defined *> AdjustedPrologues;
989 DenseSet<Defined *> Prologues;
893990 std::vector<Relocation *> MorestackCalls;
894991
895992 for (Relocation &Rel : Relocations) {
......@@ -898,15 +995,9 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
898995 if (Rel.Sym->isLocal())
899996 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
907998 // Ignore calls into the split-stack api.
908 if (D->getName().startswith("__morestack")) {
909 if (D->getName().equals("__morestack"))
999 if (Rel.Sym->getName().startswith("__morestack")) {
1000 if (Rel.Sym->getName().equals("__morestack"))
9101001 MorestackCalls.push_back(&Rel);
9111002 continue;
9121003 }
......@@ -914,24 +1005,36 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
9141005 // A relocation to non-function isn't relevant. Sometimes
9151006 // __morestack is not marked as a function, so this check comes
9161007 // after the name check.
917 if (D->Type != STT_FUNC)
1008 if (Rel.Sym->Type != STT_FUNC)
9181009 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))
9211022 continue;
9221023
9231024 if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {
924 if (Target->adjustPrologueForCrossSplitStack(Buf + F->Value, End)) {
925 AdjustedPrologues.insert(F);
1025 Prologues.insert(F);
1026 if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value),
1027 End, F->StOther))
9261028 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");
9281033 }
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");
9331034 }
934 switchMorestackCallsToMorestackNonSplit(AdjustedPrologues, MorestackCalls);
1035
1036 if (Target->NeedsMoreStackNonSplit)
1037 switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls);
9351038}
9361039
9371040template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
......@@ -960,10 +1063,23 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
9601063 return;
9611064 }
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
9631079 // Copy section contents from source object file to output file
9641080 // and then apply relocations.
965 memcpy(Buf + OutSecOff, Data.data(), Data.size());
966 uint8_t *BufEnd = Buf + OutSecOff + Data.size();
1081 memcpy(Buf + OutSecOff, data().data(), data().size());
1082 uint8_t *BufEnd = Buf + OutSecOff + data().size();
9671083 relocate<ELFT>(Buf, BufEnd);
9681084}
9691085
......@@ -1014,7 +1130,7 @@ template <class ELFT> void EhInputSection::split() {
10141130template <class ELFT, class RelTy>
10151131void EhInputSection::split(ArrayRef<RelTy> Rels) {
10161132 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;) {
10181134 size_t Size = readEhRecordSize(this, Off);
10191135 Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
10201136 // The empty record is the end marker.
......@@ -1094,65 +1210,32 @@ void MergeInputSection::splitIntoPieces() {
10941210 assert(Pieces.empty());
10951211
10961212 if (Flags & SHF_STRINGS)
1097 splitStrings(Data, Entsize);
1213 splitStrings(data(), Entsize);
10981214 else
1099 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;
1215 splitNonStrings(data(), Entsize);
11301216}
11311217
11321218SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
1133 // Find a piece starting at a given offset.
1134 auto It = OffsetMap.find(Offset);
1135 if (It != OffsetMap.end())
1136 return &Pieces[It->second];
1219 if (this->data().size() <= Offset)
1220 fatal(toString(this) + ": offset is outside the section");
11371221
11381222 // 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.
1140 return findSectionPiece(this, Offset);
1223 // In that case we need to do a binary search of the original section piece vector.
1224 auto It2 =
1225 llvm::upper_bound(Pieces, Offset, [](uint64_t Offset, SectionPiece P) {
1226 return Offset < P.InputOff;
1227 });
1228 return &It2[-1];
11411229}
11421230
11431231// Returns the offset in an output section for a given input offset.
11441232// Because contents of a mergeable section is not contiguous in output,
11451233// it is not just an addition to a base output offset.
11461234uint64_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
11521235 // If Offset is not at beginning of a section piece, it is not in the map.
11531236 // In that case we need to search from the original section piece vector.
11541237 const SectionPiece &Piece =
1155 *findSectionPiece(const_cast<MergeInputSection *>(this), Offset);
1238 *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
11561239 uint64_t Addend = Offset - Piece.InputOff;
11571240 return Piece.OutputOff + Addend;
11581241}
deps/lld/ELF/InputSection.h+23-15
......@@ -115,7 +115,12 @@ public:
115115 return cast_or_null<ObjFile<ELFT>>(File);
116116 }
117117
118 ArrayRef<uint8_t> Data;
118 ArrayRef<uint8_t> data() const {
119 if (UncompressedSize >= 0 && !UncompressedBuf)
120 uncompress();
121 return RawData;
122 }
123
119124 uint64_t getOffsetInFile() const;
120125
121126 // True if this section has already been placed to a linker script
......@@ -169,11 +174,6 @@ public:
169174 template <class ELFT>
170175 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
177177 // Returns a source location string. Used to construct an error message.
178178 template <class ELFT> std::string getLocation(uint64_t Offset);
179179 std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
......@@ -200,15 +200,21 @@ public:
200200
201201
202202 template <typename T> llvm::ArrayRef<T> getDataAs() const {
203 size_t S = Data.size();
203 size_t S = data().size();
204204 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));
206206 }
207207
208private:
209 // A pointer that owns decompressed data if a section is compressed by zlib.
208protected:
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.
210215 // 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;
212218};
213219
214220// SectionPiece represents a piece of splittable section contents.
......@@ -247,7 +253,6 @@ public:
247253 // Splittable sections are handled as a sequence of data
248254 // rather than a single large blob of data.
249255 std::vector<SectionPiece> Pieces;
250 llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
251256
252257 // Returns I'th piece's data. This function is very hot when
253258 // string merging is enabled, so we want to inline.
......@@ -255,8 +260,8 @@ public:
255260 llvm::CachedHashStringRef getData(size_t I) const {
256261 size_t Begin = Pieces[I].InputOff;
257262 size_t End =
258 (Pieces.size() - 1 == I) ? Data.size() : Pieces[I + 1].InputOff;
259 return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};
263 (Pieces.size() - 1 == I) ? data().size() : Pieces[I + 1].InputOff;
264 return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
260265 }
261266
262267 // Returns the SectionPiece at a given input section offset.
......@@ -277,7 +282,9 @@ struct EhSectionPiece {
277282 unsigned FirstRelocation)
278283 : 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
282289 size_t InputOff;
283290 ssize_t OutputOff = -1;
......@@ -353,6 +360,7 @@ private:
353360
354361// The list of all input sections.
355362extern std::vector<InputSectionBase *> InputSections;
363
356364} // namespace elf
357365
358366std::string toString(const elf::InputSectionBase *);
deps/lld/ELF/LTO.cpp+25-23
......@@ -67,9 +67,10 @@ static std::string getThinLTOOutputFile(StringRef ModulePath) {
6767static lto::Config createConfig() {
6868 lto::Config C;
6969
70 // LLD supports the new relocations.
70 // LLD supports the new relocations and address-significance tables.
7171 C.Options = InitTargetOptionsFromCodeGenFlags();
7272 C.Options.RelaxELFRelocations = true;
73 C.Options.EmitAddrsig = true;
7374
7475 // Always emit a section per function/datum with LTO.
7576 C.Options.FunctionSections = true;
......@@ -87,6 +88,7 @@ static lto::Config createConfig() {
8788 C.DiagHandler = diagnosticHandler;
8889 C.OptLevel = Config->LTOO;
8990 C.CPU = GetCPUStr();
91 C.MAttrs = GetMAttrs();
9092
9193 // Set up a custom pipeline if we've been asked to.
9294 C.OptPipeline = Config->LTONewPmPasses;
......@@ -101,6 +103,14 @@ static lto::Config createConfig() {
101103 C.DebugPassManager = Config->LTODebugPassManager;
102104 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
104114 if (Config->SaveTemps)
105115 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
106116 /*UseInputModulePath*/ true));
......@@ -108,18 +118,14 @@ static lto::Config createConfig() {
108118}
109119
110120BitcodeCompiler::BitcodeCompiler() {
121 // Initialize IndexFile.
122 if (!Config->ThinLTOIndexOnlyArg.empty())
123 IndexFile = openFile(Config->ThinLTOIndexOnlyArg);
124
111125 // Initialize LTOObj.
112126 lto::ThinBackend Backend;
113
114127 if (Config->ThinLTOIndexOnly) {
115 StringRef Path = Config->ThinLTOIndexOnlyArg;
116 if (!Path.empty())
117 IndexFile = openFile(Path);
118
119 auto OnIndexWrite = [&](const std::string &Identifier) {
120 ObjectToIndexFileState[Identifier] = true;
121 };
122
128 auto OnIndexWrite = [&](StringRef S) { ThinIndices.erase(S); };
123129 Backend = lto::createWriteIndexesThinBackend(
124130 Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
125131 Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
......@@ -132,10 +138,10 @@ BitcodeCompiler::BitcodeCompiler() {
132138
133139 // Initialize UsedStartStop.
134140 for (Symbol *Sym : Symtab->getSymbols()) {
135 StringRef Name = Sym->getName();
141 StringRef S = Sym->getName();
136142 for (StringRef Prefix : {"__start_", "__stop_"})
137 if (Name.startswith(Prefix))
138 UsedStartStop.insert(Name.substr(Prefix.size()));
143 if (S.startswith(Prefix))
144 UsedStartStop.insert(S.substr(Prefix.size()));
139145 }
140146}
141147
......@@ -151,7 +157,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
151157 bool IsExec = !Config->Shared && !Config->Relocatable;
152158
153159 if (Config->ThinLTOIndexOnly)
154 ObjectToIndexFileState.insert({Obj.getName(), false});
160 ThinIndices.insert(Obj.getName());
155161
156162 ArrayRef<Symbol *> Syms = F.getSymbols();
157163 ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
......@@ -240,15 +246,11 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
240246 Cache));
241247
242248 // Emit empty index files for non-indexed files
243 if (Config->ThinLTOIndexOnly) {
244 for (auto &Identifier : ObjectToIndexFileState)
245 if (!Identifier.getValue()) {
246 std::string Path = getThinLTOOutputFile(Identifier.getKey());
247 openFile(Path + ".thinlto.bc");
248
249 if (Config->ThinLTOEmitImportsFiles)
250 openFile(Path + ".imports");
251 }
249 for (StringRef S : ThinIndices) {
250 std::string Path = getThinLTOOutputFile(S);
251 openFile(Path + ".thinlto.bc");
252 if (Config->ThinLTOEmitImportsFiles)
253 openFile(Path + ".imports");
252254 }
253255
254256 // If LazyObjFile has not been added to link, emit empty index files.
deps/lld/ELF/LTO.h+1-1
......@@ -55,7 +55,7 @@ private:
5555 std::vector<std::unique_ptr<MemoryBuffer>> Files;
5656 llvm::DenseSet<StringRef> UsedStartStop;
5757 std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
58 llvm::StringMap<bool> ObjectToIndexFileState;
58 llvm::DenseSet<StringRef> ThinIndices;
5959};
6060} // namespace elf
6161} // namespace lld
deps/lld/ELF/LinkerScript.cpp+10-23
......@@ -169,7 +169,7 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
169169 // Define a symbol.
170170 Symbol *Sym;
171171 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,
173173 /*CanOmitFromDynSym*/ false,
174174 /*File*/ nullptr);
175175 ExprValue Value = Cmd->Expression();
......@@ -202,13 +202,14 @@ static void declareSymbol(SymbolAssignment *Cmd) {
202202 // We can't calculate final value right now.
203203 Symbol *Sym;
204204 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,
206206 /*CanOmitFromDynSym*/ false,
207207 /*File*/ nullptr);
208208 replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
209209 STT_NOTYPE, 0, 0, nullptr);
210210 Cmd->Sym = cast<Defined>(Sym);
211211 Cmd->Provide = false;
212 Sym->ScriptDefined = true;
212213}
213214
214215// This method is used to handle INSERT AFTER statement. Here we rebuild
......@@ -414,18 +415,16 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
414415
415416void LinkerScript::discard(ArrayRef<InputSection *> V) {
416417 for (InputSection *S : V) {
417 if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
418 S == InX::DynStrTab || S == InX::RelaPlt || S == InX::RelaDyn ||
419 S == InX::RelrDyn)
418 if (S == In.ShStrTab || S == In.RelaDyn || S == In.RelrDyn)
420419 error("discarding " + S->Name + " section is not allowed");
421420
422421 // You can discard .hash and .gnu.hash sections by linker scripts. Since
423422 // they are synthesized sections, we need to handle them differently than
424423 // other regular sections.
425 if (S == InX::GnuHashTab)
426 InX::GnuHashTab = nullptr;
427 if (S == InX::HashTab)
428 InX::HashTab = nullptr;
424 if (S == In.GnuHashTab)
425 In.GnuHashTab = nullptr;
426 if (S == In.HashTab)
427 In.HashTab = nullptr;
429428
430429 S->Assigned = false;
431430 S->Live = false;
......@@ -701,6 +700,7 @@ uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {
701700}
702701
703702void LinkerScript::output(InputSection *S) {
703 assert(Ctx->OutSec == S->getParent());
704704 uint64_t Before = advance(0, 1);
705705 uint64_t Pos = advance(S->getSize(), S->Alignment);
706706 S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
......@@ -816,21 +816,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
816816 // Handle a single input section description command.
817817 // It calculates and assigns the offsets for each section and also
818818 // updates the output section size.
819 auto *Cmd = cast<InputSectionDescription>(Base);
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());
819 for (InputSection *Sec : cast<InputSectionDescription>(Base)->Sections)
832820 output(Sec);
833 }
834821 }
835822}
836823
deps/lld/ELF/LinkerScript.h+7-5
......@@ -30,12 +30,13 @@ namespace lld {
3030namespace elf {
3131
3232class Defined;
33class Symbol;
34class InputSectionBase;
3533class InputSection;
36class OutputSection;
3734class InputSectionBase;
35class InputSectionBase;
36class OutputSection;
3837class SectionBase;
38class Symbol;
39class ThunkSection;
3940
4041// This represents an r-value in the linker script.
4142struct ExprValue {
......@@ -145,7 +146,9 @@ struct MemoryRegion {
145146// Also it may be surrounded with SORT() command, so contains sorting rules.
146147struct SectionPattern {
147148 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
148 : ExcludedFilePat(Pat1), SectionPat(Pat2) {}
149 : ExcludedFilePat(Pat1), SectionPat(Pat2),
150 SortOuter(SortSectionPolicy::Default),
151 SortInner(SortSectionPolicy::Default) {}
149152
150153 StringMatcher ExcludedFilePat;
151154 StringMatcher SectionPat;
......@@ -153,7 +156,6 @@ struct SectionPattern {
153156 SortSectionPolicy SortInner;
154157};
155158
156class ThunkSection;
157159struct InputSectionDescription : BaseCommand {
158160 InputSectionDescription(StringRef FilePattern)
159161 : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
deps/lld/ELF/MapFile.cpp+6-5
......@@ -126,7 +126,7 @@ static void printEhFrame(raw_ostream &OS, OutputSection *OSec) {
126126 };
127127
128128 // Gather section pieces.
129 for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) {
129 for (const CieRecord *Rec : In.EhFrame->getCieRecords()) {
130130 Add(*Rec->Cie);
131131 for (const EhSectionPiece *Fde : Rec->Fdes)
132132 Add(*Fde);
......@@ -163,17 +163,18 @@ void elf::writeMapFile() {
163163 OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)
164164 << " Size Align Out In Symbol\n";
165165
166 OutputSection* OSec = nullptr;
166167 for (BaseCommand *Base : Script->SectionCommands) {
167168 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
168169 if (Cmd->Provide && !Cmd->Sym)
169170 continue;
170 //FIXME: calculate and print LMA.
171 writeHeader(OS, Cmd->Addr, 0, Cmd->Size, 1);
171 uint64_t LMA = OSec ? OSec->getLMA() + Cmd->Addr - OSec->getVA(0) : 0;
172 writeHeader(OS, Cmd->Addr, LMA, Cmd->Size, 1);
172173 OS << Cmd->CommandString << '\n';
173174 continue;
174175 }
175176
176 auto *OSec = cast<OutputSection>(Base);
177 OSec = cast<OutputSection>(Base);
177178 writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
178179 OS << OSec->Name << '\n';
179180
......@@ -181,7 +182,7 @@ void elf::writeMapFile() {
181182 for (BaseCommand *Base : OSec->SectionCommands) {
182183 if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
183184 for (InputSection *IS : ISD->Sections) {
184 if (IS == InX::EhFrame) {
185 if (IS == In.EhFrame) {
185186 printEhFrame(OS, OSec);
186187 continue;
187188 }
deps/lld/ELF/MarkLive.cpp+11-4
......@@ -45,7 +45,7 @@ using namespace lld::elf;
4545template <class ELFT>
4646static typename ELFT::uint getAddend(InputSectionBase &Sec,
4747 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,
4949 Rel.getType(Config->IsMips64EL));
5050}
5151
......@@ -250,9 +250,10 @@ template <class ELFT> static void doGcSections() {
250250
251251 if (Sec->Flags & SHF_LINK_ORDER)
252252 continue;
253 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
253
254 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) {
254255 Enqueue(Sec, 0);
255 else if (isValidCIdentifier(Sec->Name)) {
256 } else if (isValidCIdentifier(Sec->Name)) {
256257 CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
257258 CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
258259 }
......@@ -267,10 +268,16 @@ template <class ELFT> static void doGcSections() {
267268// input sections. This function make some or all of them on
268269// so that they are emitted to the output file.
269270template <class ELFT> void elf::markLive() {
270 // If -gc-sections is missing, no sections are removed.
271271 if (!Config->GcSections) {
272 // If -gc-sections is missing, no sections are removed.
272273 for (InputSectionBase *Sec : InputSections)
273274 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;
274281 return;
275282 }
276283
deps/lld/ELF/Options.td+23-1
......@@ -42,6 +42,12 @@ defm compress_debug_sections:
4242
4343defm 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
4551defm library_path:
4652 Eq<"library-path", "Add a directory to the library search path">, MetaVarName<"<dir>">;
4753
......@@ -68,6 +74,10 @@ defm as_needed: B<"as-needed",
6874defm call_graph_ordering_file:
6975 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
7181// -chroot doesn't have a help text because it is an internal option.
7282def chroot: Separate<["--", "-"], "chroot">;
7383
......@@ -132,7 +142,7 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">,
132142defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
133143
134144defm execute_only: B<"execute-only",
135 "Do not mark executable sections readable",
145 "Mark executable sections unreadable",
136146 "Mark executable sections readable (default)">;
137147
138148defm export_dynamic: B<"export-dynamic",
......@@ -245,6 +255,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags",
245255 "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
246256 "Use SHT_RELR / DT_RELR* tags (default)">;
247257
258def pic_veneer: F<"pic-veneer">,
259 HelpText<"Always generate position independent thunks (veneers)">;
260
248261defm pie: B<"pie",
249262 "Create a position independent executable",
250263 "Do not create a position independent executable (default)">;
......@@ -315,6 +328,10 @@ defm threads: B<"threads",
315328 "Run the linker multi-threaded (default)",
316329 "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
318335def trace: F<"trace">, HelpText<"Print the names of the input files">;
319336
320337defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
......@@ -348,6 +365,10 @@ defm warn_common: B<"warn-common",
348365 "Warn about duplicate common symbols",
349366 "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
351372defm warn_symbol_ordering: B<"warn-symbol-ordering",
352373 "Warn about problems with the symbol ordering file (default)",
353374 "Do not warn about problems with the symbol ordering file">;
......@@ -440,6 +461,7 @@ def: F<"plugin-opt=debug-pass-manager">,
440461def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, HelpText<"Alias for -disable-verify">;
441462def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">,
442463 HelpText<"Directory to store .dwo files when LTO and debug fission are used">;
464def plugin_opt_emit_llvm: F<"plugin-opt=emit-llvm">;
443465def: J<"plugin-opt=jobs=">, Alias<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">;
444466def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">;
445467def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">;
deps/lld/ELF/OutputSections.cpp+14-12
......@@ -25,6 +25,7 @@
2525using namespace llvm;
2626using namespace llvm::dwarf;
2727using namespace llvm::object;
28using namespace llvm::support::endian;
2829using namespace llvm::ELF;
2930
3031using namespace lld;
......@@ -32,7 +33,6 @@ using namespace lld::elf;
3233
3334uint8_t Out::First;
3435PhdrEntry *Out::TlsPhdr;
35OutputSection *Out::DebugInfo;
3636OutputSection *Out::ElfHeader;
3737OutputSection *Out::ProgramHeaders;
3838OutputSection *Out::PreinitArray;
......@@ -171,11 +171,12 @@ void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) {
171171
172172// Fill [Buf, Buf + Size) with Filler.
173173// 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) {
175176 size_t I = 0;
176177 for (; I + 4 < Size; I += 4)
177 memcpy(Buf + I, &Filler, 4);
178 memcpy(Buf + I, &Filler, Size - I);
178 memcpy(Buf + I, Filler.data(), 4);
179 memcpy(Buf + I, Filler.data(), Size - I);
179180}
180181
181182// Compress section contents if this section contains debug info.
......@@ -236,8 +237,9 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
236237
237238 // Write leading padding.
238239 std::vector<InputSection *> Sections = getInputSections(this);
239 uint32_t Filler = getFiller();
240 if (Filler)
240 std::array<uint8_t, 4> Filler = getFiller();
241 bool NonZeroFiller = read32(Filler.data()) != 0;
242 if (NonZeroFiller)
241243 fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
242244
243245 parallelForEachN(0, Sections.size(), [&](size_t I) {
......@@ -245,7 +247,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
245247 IS->writeTo<ELFT>(Buf);
246248
247249 // Fill gaps between sections.
248 if (Filler) {
250 if (NonZeroFiller) {
249251 uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
250252 uint8_t *End;
251253 if (I + 1 == Sections.size())
......@@ -270,13 +272,13 @@ static void finalizeShtGroup(OutputSection *OS,
270272
271273 // sh_link field for SHT_GROUP sections should contain the section index of
272274 // the symbol table.
273 OS->Link = InX::SymTab->getParent()->SectionIndex;
275 OS->Link = In.SymTab->getParent()->SectionIndex;
274276
275277 // sh_info then contain index of an entry in symbol table section which
276278 // provides signature of the section group.
277279 ObjFile<ELFT> *Obj = Section->getFile<ELFT>();
278280 ArrayRef<Symbol *> Symbols = Obj->getSymbols();
279 OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]);
281 OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
280282}
281283
282284template <class ELFT> void OutputSection::finalize() {
......@@ -308,7 +310,7 @@ template <class ELFT> void OutputSection::finalize() {
308310 if (isa<SyntheticSection>(First))
309311 return;
310312
311 Link = InX::SymTab->getParent()->SectionIndex;
313 Link = In.SymTab->getParent()->SectionIndex;
312314 // sh_info for SHT_REL[A] sections should contain the section header index of
313315 // the section to which the relocation applies.
314316 InputSectionBase *S = First->getRelocatedSection();
......@@ -406,12 +408,12 @@ void OutputSection::sortInitFini() {
406408 sort([](InputSectionBase *S) { return getPriority(S->Name); });
407409}
408410
409uint32_t OutputSection::getFiller() {
411std::array<uint8_t, 4> OutputSection::getFiller() {
410412 if (Filler)
411413 return *Filler;
412414 if (Flags & SHF_EXECINSTR)
413415 return Target->TrapInstr;
414 return 0;
416 return {0, 0, 0, 0};
415417}
416418
417419template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
deps/lld/ELF/OutputSections.h+3-3
......@@ -17,6 +17,7 @@
1717#include "lld/Common/LLVM.h"
1818#include "llvm/MC/StringTableBuilder.h"
1919#include "llvm/Object/ELF.h"
20#include <array>
2021
2122namespace lld {
2223namespace elf {
......@@ -94,7 +95,7 @@ public:
9495 Expr SubalignExpr;
9596 std::vector<BaseCommand *> SectionCommands;
9697 std::vector<StringRef> Phdrs;
97 llvm::Optional<uint32_t> Filler;
98 llvm::Optional<std::array<uint8_t, 4>> Filler;
9899 ConstraintKind Constraint = ConstraintKind::NoConstraint;
99100 std::string Location;
100101 std::string MemoryRegionName;
......@@ -117,7 +118,7 @@ private:
117118 std::vector<uint8_t> ZDebugHeader;
118119 llvm::SmallVector<char, 1> CompressedData;
119120
120 uint32_t getFiller();
121 std::array<uint8_t, 4> getFiller();
121122};
122123
123124int getPriority(StringRef S);
......@@ -130,7 +131,6 @@ std::vector<InputSection *> getInputSections(OutputSection* OS);
130131struct Out {
131132 static uint8_t First;
132133 static PhdrEntry *TlsPhdr;
133 static OutputSection *DebugInfo;
134134 static OutputSection *ElfHeader;
135135 static OutputSection *ProgramHeaders;
136136 static OutputSection *PreinitArray;
deps/lld/ELF/Relocations.cpp+215-150
......@@ -50,6 +50,7 @@
5050#include "SyntheticSections.h"
5151#include "Target.h"
5252#include "Thunks.h"
53#include "lld/Common/ErrorHandler.h"
5354#include "lld/Common/Memory.h"
5455#include "lld/Common/Strings.h"
5556#include "llvm/ADT/SmallSet.h"
......@@ -65,6 +66,14 @@ using namespace llvm::support::endian;
6566using namespace lld;
6667using 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
6877// Construct a message in the following format.
6978//
7079// >>> defined in /home/alice/src/foo.o
......@@ -72,8 +81,13 @@ using namespace lld::elf;
7281// >>> /home/alice/src/bar.o:(.text+0x1)
7382static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
7483 uint64_t Off) {
75 std::string Msg =
76 "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";
84 std::string Msg = "\n>>> defined in ";
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 ";
7791 std::string Src = S.getSrcMsg(Sym, Off);
7892 if (!Src.empty())
7993 Msg += Src + "\n>>> ";
......@@ -90,12 +104,12 @@ static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,
90104 InputSectionBase &C, uint64_t Offset,
91105 int64_t Addend, RelExpr Expr) {
92106 if (Expr == R_MIPS_TLSLD) {
93 InX::MipsGot->addTlsIndex(*C.File);
107 In.MipsGot->addTlsIndex(*C.File);
94108 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
95109 return 1;
96110 }
97111 if (Expr == R_MIPS_TLSGD) {
98 InX::MipsGot->addDynTlsEntry(*C.File, Sym);
112 In.MipsGot->addDynTlsEntry(*C.File, Sym);
99113 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
100114 return 1;
101115 }
......@@ -128,17 +142,17 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,
128142
129143 auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) {
130144 if (Dyn)
131 InX::RelaDyn->addReloc(Type, InX::Got, Off, Dest);
145 In.RelaDyn->addReloc(Type, In.Got, Off, Dest);
132146 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});
134148 };
135149
136150 // Local Dynamic is for access to module local TLS variables, while still
137151 // being suitable for being dynamically loaded via dlopen.
138152 // GOT[e0] is the module index, with a special value of 0 for the current
139153 // module. GOT[e1] is unused. There only needs to be one module index entry.
140 if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) {
141 AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
154 if (Expr == R_TLSLD_PC && In.Got->addTlsIndex()) {
155 AddTlsReloc(In.Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
142156 NeedDynId ? nullptr : &Sym, NeedDynId);
143157 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
144158 return 1;
......@@ -148,8 +162,8 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,
148162 // the module index and offset of symbol in TLS block we can fill these in
149163 // using static GOT relocations.
150164 if (Expr == R_TLSGD_PC) {
151 if (InX::Got->addDynTlsEntry(Sym)) {
152 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
165 if (In.Got->addDynTlsEntry(Sym)) {
166 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
153167 AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId);
154168 AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym,
155169 NeedDynOff);
......@@ -165,9 +179,6 @@ template <class ELFT>
165179static unsigned
166180handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
167181 typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
168 if (!(C.Flags & SHF_ALLOC))
169 return 0;
170
171182 if (!Sym.isTls())
172183 return 0;
173184
......@@ -176,12 +187,12 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
176187 if (Config->EMachine == EM_MIPS)
177188 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) &&
180191 Config->Shared) {
181 if (InX::Got->addDynTlsEntry(Sym)) {
182 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
183 InX::RelaDyn->addReloc(
184 {Target->TlsDescRel, InX::Got, Off, !Sym.IsPreemptible, &Sym, 0});
192 if (In.Got->addDynTlsEntry(Sym)) {
193 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
194 In.RelaDyn->addReloc(
195 {Target->TlsDescRel, In.Got, Off, !Sym.IsPreemptible, &Sym, 0});
185196 }
186197 if (Expr != R_TLSDESC_CALL)
187198 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
......@@ -199,9 +210,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
199210 }
200211 if (Expr == R_TLSLD_HINT)
201212 return 1;
202 if (InX::Got->addTlsIndex())
203 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got,
204 InX::Got->getTlsIndexOff(), nullptr);
213 if (In.Got->addTlsIndex())
214 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got,
215 In.Got->getTlsIndexOff(), nullptr);
205216 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
206217 return 1;
207218 }
......@@ -223,29 +234,29 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
223234 return 1;
224235 }
225236 if (!Sym.isInGot()) {
226 InX::Got->addEntry(Sym);
237 In.Got->addEntry(Sym);
227238 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});
229241 }
230242 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
231243 return 1;
232244 }
233245
234 if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT,
235 R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) {
246 if (isRelExprOneOf<R_TLSDESC, R_AARCH64_TLSDESC_PAGE, R_TLSDESC_CALL,
247 R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) {
236248 if (Config->Shared) {
237 if (InX::Got->addDynTlsEntry(Sym)) {
238 uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
239 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, Off, &Sym);
249 if (In.Got->addDynTlsEntry(Sym)) {
250 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
251 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym);
240252
241253 // If the symbol is preemptible we need the dynamic linker to write
242254 // the offset too.
243255 uint64_t OffsetOff = Off + Config->Wordsize;
244256 if (Sym.IsPreemptible)
245 InX::RelaDyn->addReloc(Target->TlsOffsetRel, InX::Got, OffsetOff,
246 &Sym);
257 In.RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff, &Sym);
247258 else
248 InX::Got->Relocations.push_back(
259 In.Got->Relocations.push_back(
249260 {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});
250261 }
251262 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
......@@ -259,9 +270,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
259270 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
260271 Offset, Addend, &Sym});
261272 if (!Sym.isInGot()) {
262 InX::Got->addEntry(Sym);
263 InX::RelaDyn->addReloc(Target->TlsGotRel, InX::Got, Sym.getGotOffset(),
264 &Sym);
273 In.Got->addEntry(Sym);
274 In.RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(),
275 &Sym);
265276 }
266277 } else {
267278 C.Relocations.push_back(
......@@ -273,13 +284,14 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
273284
274285 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
275286 // 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) &&
277289 !Config->Shared && !Sym.IsPreemptible) {
278290 C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});
279291 return 1;
280292 }
281293
282 if (Expr == R_TLSDESC_CALL)
294 if (Expr == R_TLSIE_HINT)
283295 return 1;
284296 return 0;
285297}
......@@ -325,24 +337,26 @@ static bool isAbsoluteValue(const Symbol &Sym) {
325337
326338// Returns true if Expr refers a PLT entry.
327339static 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);
329342}
330343
331344// Returns true if Expr refers a GOT entry. Note that this function
332345// returns false for TLS variables even though they need GOT, because
333346// TLS variables uses GOT differently than the regular variables.
334347static bool needsGot(RelExpr Expr) {
335 return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
336 R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
337 R_GOT_FROM_END>(Expr);
348 return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
349 R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
350 R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END,
351 R_GOT_PLT>(Expr);
338352}
339353
340354// True if this expression is of the form Sym - X, where X is a position in the
341355// file (PC, or GOT for example).
342356static bool isRelExpr(RelExpr Expr) {
343357 return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
344 R_PPC_CALL, R_PPC_CALL_PLT, R_PAGE_PC,
345 R_RELAX_GOT_PC>(Expr);
358 R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC,
359 R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr);
346360}
347361
348362// Returns true if a given relocation can be computed at link-time.
......@@ -357,18 +371,19 @@ static bool isRelExpr(RelExpr Expr) {
357371static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
358372 InputSectionBase &S, uint64_t RelOff) {
359373 // These expressions always compute a constant
360 if (isRelExprOneOf<
361 R_GOT_FROM_END, R_GOT_OFF, R_TLSLD_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
362 R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
363 R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
364 R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END,
365 R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT,
366 R_TLSLD_HINT>(E))
374 if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF,
375 R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
376 R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD,
377 R_AARCH64_GOT_PAGE_PC, R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC,
378 R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT,
379 R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT,
380 R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, R_HINT,
381 R_TLSLD_HINT, R_TLSIE_HINT>(E))
367382 return true;
368383
369384 // These never do, except if the entire file is position dependent or if
370385 // 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)
372387 return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
373388
374389 if (Sym.IsPreemptible)
......@@ -414,10 +429,14 @@ static RelExpr toPlt(RelExpr Expr) {
414429 return R_PPC_CALL_PLT;
415430 case R_PC:
416431 return R_PLT_PC;
417 case R_PAGE_PC:
418 return R_PLT_PAGE_PC;
432 case R_AARCH64_PAGE_PC:
433 return R_AARCH64_PLT_PAGE_PC;
434 case R_AARCH64_GOT_PAGE_PC:
435 return R_AARCH64_GOT_PAGE_PC_PLT;
419436 case R_ABS:
420437 return R_PLT;
438 case R_GOT:
439 return R_GOT_PLT;
421440 default:
422441 return Expr;
423442 }
......@@ -466,7 +485,7 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
466485 SmallSet<SharedSymbol *, 4> Ret;
467486 for (const Elf_Sym &S : File.getGlobalELFSyms()) {
468487 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)
470489 continue;
471490 StringRef Name = check(S.getName(File.getStringTable()));
472491 Symbol *Sym = Symtab->find(Name);
......@@ -489,6 +508,7 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
489508 Sym.PltIndex = Old.PltIndex;
490509 Sym.GotIndex = Old.GotIndex;
491510 Sym.VerdefIndex = Old.VerdefIndex;
511 Sym.PPC64BranchltIndex = Old.PPC64BranchltIndex;
492512 Sym.IsPreemptible = true;
493513 Sym.ExportDynamic = true;
494514 Sym.IsUsedInRegularObj = true;
......@@ -549,9 +569,9 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
549569 BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
550570 SymSize, SS.Alignment);
551571 if (IsReadOnly)
552 InX::BssRelRo->getParent()->addSection(Sec);
572 In.BssRelRo->getParent()->addSection(Sec);
553573 else
554 InX::Bss->getParent()->addSection(Sec);
574 In.Bss->getParent()->addSection(Sec);
555575
556576 // Look through the DSO's dynamic symbol table for aliases and create a
557577 // dynamic symbol for each one. This causes the copy relocation to correctly
......@@ -559,7 +579,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
559579 for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
560580 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);
563583}
564584
565585// 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,
583603 if (PairTy == R_MIPS_NONE)
584604 return 0;
585605
586 const uint8_t *Buf = Sec.Data.data();
606 const uint8_t *Buf = Sec.data().data();
587607 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
588608
589609 // 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,
611631 if (RelTy::IsRela) {
612632 Addend = getAddend<ELFT>(Rel);
613633 } else {
614 const uint8_t *Buf = Sec.Data.data();
634 const uint8_t *Buf = Sec.data().data();
615635 Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
616636 }
617637
......@@ -627,9 +647,6 @@ static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
627647// Returns true if this function printed out an error message.
628648static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
629649 uint64_t Offset) {
630 if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
631 return false;
632
633650 if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())
634651 return false;
635652
......@@ -646,6 +663,10 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
646663 Msg += Src + "\n>>> ";
647664 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
649670 if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
650671 Config->NoinhibitExec) {
651672 warn(Msg);
......@@ -700,7 +721,7 @@ public:
700721 while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)
701722 ++I;
702723 if (I == Pieces.size())
703 return Off;
724 fatal(".eh_frame: relocation is not in any piece");
704725
705726 // Pieces must be contiguous, so there must be no holes in between.
706727 assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");
......@@ -726,13 +747,13 @@ static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,
726747 // RelrDyn sections don't support odd offsets. Also, RelrDyn sections
727748 // don't store the addend values, so we must write it to the relocated
728749 // address.
729 if (InX::RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
750 if (In.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
730751 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});
732753 return;
733754 }
734 InX::RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend,
735 Expr, Type);
755 In.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, Expr,
756 Type);
736757}
737758
738759template <class ELFT, class GotPltSection>
......@@ -745,9 +766,16 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
745766}
746767
747768template <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;
751779 uint64_t Off = Sym.getGotOffset();
752780
753781 // 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) {
760788 bool IsLinkTimeConstant =
761789 !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
762790 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});
764792 return;
765793 }
766794
767795 // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
768796 // the GOT slot will be fixed at load-time.
769797 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);
771799 return;
772800 }
773 InX::RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel,
774 InX::Got, Off, &Sym, 0,
775 Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel);
801 In.RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got,
802 Off, &Sym, 0, Sym.IsPreemptible ? R_ADDEND : R_ABS,
803 Target->GotRel);
776804}
777805
778806// 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,
825853 addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
826854 return;
827855 } 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
830858 // MIPS ABI turns using of GOT and dynamic relocations inside out.
831859 // While regular ABI uses dynamic relocations to fill up GOT entries
......@@ -843,7 +871,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
843871 // a dynamic relocation.
844872 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
845873 if (Config->EMachine == EM_MIPS)
846 InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
874 In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
847875 return;
848876 }
849877 }
......@@ -930,10 +958,9 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
930958 "' cannot be preempted; recompile with -fPIE" +
931959 getLocation(Sec, Sym, Offset));
932960 if (!Sym.isInPlt())
933 addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
934 Sym);
961 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
935962 if (!Sym.isDefined())
936 replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0);
963 replaceWithDefined(Sym, In.Plt, getPltEntryOffset(Sym.PltIndex), 0);
937964 Sym.NeedsPltAddr = true;
938965 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
939966 return;
......@@ -967,7 +994,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
967994 if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
968995 return;
969996
970 const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset;
997 const uint8_t *RelocatedAddr = Sec.data().begin() + Rel.r_offset;
971998 RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
972999
9731000 // Ignore "hint" relocations because they are only markers for relaxation.
......@@ -985,18 +1012,28 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
9851012 // all dynamic symbols that can be resolved within the executable will
9861013 // actually be resolved that way at runtime, because the main exectuable
9871014 // 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 }
9891025 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)) {
9911027 Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
992 else if (!Sym.IsPreemptible)
1028 } else if (!Sym.IsPreemptible) {
9931029 Expr = fromPlt(Expr);
1030 }
9941031
9951032 // This relocation does not require got entry, but it is relative to got and
9961033 // needs it to be created. Here we request for that.
9971034 if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
9981035 R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
999 InX::Got->HasGotOffRel = true;
1036 In.Got->HasGotOffRel = true;
10001037
10011038 // Read an addend.
10021039 int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
......@@ -1012,11 +1049,10 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
10121049 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
10131050 if (needsPlt(Expr) && !Sym.isInPlt()) {
10141051 if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
1015 addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
1016 Target->IRelativeRel, Sym);
1017 else
1018 addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
1052 addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
10191053 Sym);
1054 else
1055 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
10201056 }
10211057
10221058 // Create a GOT slot if a relocation needs GOT.
......@@ -1029,7 +1065,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
10291065 // See "Global Offset Table" in Chapter 5 in the following document
10301066 // for detailed description:
10311067 // 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);
10331069 } else if (!Sym.isInGot()) {
10341070 addGotEntry<ELFT>(Sym);
10351071 }
......@@ -1047,6 +1083,11 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
10471083
10481084 for (auto I = Rels.begin(), End = Rels.end(); I != End;)
10491085 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{});
10501091}
10511092
10521093template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
......@@ -1056,6 +1097,43 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
10561097 scanRelocs<ELFT>(S, S.rels<ELFT>());
10571098}
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
10591137// Thunk Implementation
10601138//
10611139// Thunks (sometimes called stubs, veneers or branch islands) are small pieces
......@@ -1158,6 +1236,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
11581236 [](const std::pair<ThunkSection *, uint32_t> &TS) {
11591237 return TS.first->getSize() == 0;
11601238 });
1239
11611240 // ISD->ThunkSections contains all created ThunkSections, including
11621241 // those inserted in previous passes. Extract the Thunks created this
11631242 // pass and order them in ascending OutSecOff.
......@@ -1173,27 +1252,11 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
11731252 // Merge sorted vectors of Thunks and InputSections by OutSecOff
11741253 std::vector<InputSection *> Tmp;
11751254 Tmp.reserve(ISD->Sections.size() + NewThunks.size());
1176 auto MergeCmp = [](const InputSection *A, const InputSection *B) {
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 };
1255
11941256 std::merge(ISD->Sections.begin(), ISD->Sections.end(),
11951257 NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),
1196 MergeCmp);
1258 mergeCmp);
1259
11971260 ISD->Sections = std::move(Tmp);
11981261 });
11991262}
......@@ -1237,20 +1300,23 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
12371300 // Find InputSectionRange within Target Output Section (TOS) that the
12381301 // InputSection (IS) that we need to precede is in.
12391302 OutputSection *TOS = IS->getParent();
1240 for (BaseCommand *BC : TOS->SectionCommands)
1241 if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
1242 if (ISD->Sections.empty())
1243 continue;
1244 InputSection *first = ISD->Sections.front();
1245 InputSection *last = ISD->Sections.back();
1246 if (IS->OutSecOff >= first->OutSecOff &&
1247 IS->OutSecOff <= last->OutSecOff) {
1248 TS = addThunkSection(TOS, ISD, IS->OutSecOff);
1249 ThunkedSections[IS] = TS;
1250 break;
1251 }
1252 }
1253 return TS;
1303 for (BaseCommand *BC : TOS->SectionCommands) {
1304 auto *ISD = dyn_cast<InputSectionDescription>(BC);
1305 if (!ISD || ISD->Sections.empty())
1306 continue;
1307
1308 InputSection *First = ISD->Sections.front();
1309 InputSection *Last = ISD->Sections.back();
1310
1311 if (IS->OutSecOff < First->OutSecOff || Last->OutSecOff < IS->OutSecOff)
1312 continue;
1313
1314 TS = addThunkSection(TOS, ISD, IS->OutSecOff);
1315 ThunkedSections[IS] = TS;
1316 return TS;
1317 }
1318
1319 return nullptr;
12541320}
12551321
12561322// Create one or more ThunkSections per OS that can be used to place Thunks.
......@@ -1271,26 +1337,29 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
12711337// allow for the creation of a short thunk.
12721338void ThunkCreator::createInitialThunkSections(
12731339 ArrayRef<OutputSection *> OutputSections) {
1340 uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
1341
12741342 forEachInputSectionDescription(
12751343 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
12761344 if (ISD->Sections.empty())
12771345 return;
1346
12781347 uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
12791348 uint32_t ISDEnd =
12801349 ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
12811350 uint32_t LastThunkLowerBound = -1;
1282 if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2)
1283 LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing;
1351 if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
1352 LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
12841353
12851354 uint32_t ISLimit;
12861355 uint32_t PrevISLimit = ISDBegin;
1287 uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing;
1356 uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
12881357
12891358 for (const InputSection *IS : ISD->Sections) {
12901359 ISLimit = IS->OutSecOff + IS->getSize();
12911360 if (ISLimit > ThunkUpperBound) {
12921361 addThunkSection(OS, ISD, PrevISLimit);
1293 ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
1362 ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
12941363 }
12951364 if (ISLimit > LastThunkLowerBound)
12961365 break;
......@@ -1304,13 +1373,14 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
13041373 InputSectionDescription *ISD,
13051374 uint64_t Off) {
13061375 auto *TS = make<ThunkSection>(OS, Off);
1307 ISD->ThunkSections.push_back(std::make_pair(TS, Pass));
1376 ISD->ThunkSections.push_back({TS, Pass});
13081377 return TS;
13091378}
13101379
13111380std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
13121381 uint64_t Src) {
13131382 std::vector<Thunk *> *ThunkVec = nullptr;
1383
13141384 // We use (section, offset) pair to find the thunk position if possible so
13151385 // that we create only one thunk for aliased symbols or ICFed sections.
13161386 if (auto *D = dyn_cast<Defined>(&Sym))
......@@ -1318,40 +1388,28 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
13181388 ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];
13191389 if (!ThunkVec)
13201390 ThunkVec = &ThunkedSymbols[&Sym];
1391
13211392 // Check existing Thunks for Sym to see if they can be reused
1322 for (Thunk *ET : *ThunkVec)
1323 if (ET->isCompatibleWith(Type) &&
1324 Target->inBranchRange(Type, Src, ET->getThunkTargetSym()->getVA()))
1325 return std::make_pair(ET, false);
1393 for (Thunk *T : *ThunkVec)
1394 if (T->isCompatibleWith(Type) &&
1395 Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA()))
1396 return std::make_pair(T, false);
1397
13261398 // No existing compatible Thunk in range, create a new one
13271399 Thunk *T = addThunk(Type, Sym);
13281400 ThunkVec->push_back(T);
13291401 return std::make_pair(T, true);
13301402}
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
13461404// Return true if the relocation target is an in range Thunk.
13471405// Return false if the relocation is not to a Thunk. If the relocation target
13481406// was originally to a Thunk, but is no longer in range we revert the
13491407// relocation back to its original non-Thunk target.
13501408bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
1351 if (Thunk *ET = Thunks.lookup(Rel.Sym)) {
1409 if (Thunk *T = Thunks.lookup(Rel.Sym)) {
13521410 if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))
13531411 return true;
1354 Rel.Sym = &ET->Destination;
1412 Rel.Sym = &T->Destination;
13551413 if (Rel.Sym->isInPlt())
13561414 Rel.Expr = toPlt(Rel.Expr);
13571415 }
......@@ -1385,11 +1443,13 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
13851443// relocation out of range error.
13861444bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
13871445 bool AddressesChanged = false;
1388 if (Pass == 0 && Target->ThunkSectionSpacing)
1446
1447 if (Pass == 0 && Target->getThunkSectionSpacing())
13891448 createInitialThunkSections(OutputSections);
1390 else if (Pass == 10)
1391 // With Thunk Size much smaller than branch range we expect to
1392 // converge quickly; if we get to 10 something has gone wrong.
1449
1450 // With Thunk Size much smaller than branch range we expect to
1451 // converge quickly; if we get to 10 something has gone wrong.
1452 if (Pass == 10)
13931453 fatal("thunk creation not converged");
13941454
13951455 // Create all the Thunks and insert them into synthetic ThunkSections. The
......@@ -1412,9 +1472,11 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
14121472 if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,
14131473 *Rel.Sym))
14141474 continue;
1475
14151476 Thunk *T;
14161477 bool IsNew;
14171478 std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src);
1479
14181480 if (IsNew) {
14191481 // Find or create a ThunkSection for the new Thunk
14201482 ThunkSection *TS;
......@@ -1425,13 +1487,16 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
14251487 TS->addThunk(T);
14261488 Thunks[T->getThunkTargetSym()] = T;
14271489 }
1490
14281491 // Redirect relocation to Thunk, we never go via the PLT to a Thunk
14291492 Rel.Sym = T->getThunkTargetSym();
14301493 Rel.Expr = fromPlt(Rel.Expr);
14311494 }
1495
14321496 for (auto &P : ISD->ThunkSections)
14331497 AddressesChanged |= P.first->assignOffsets();
14341498 });
1499
14351500 for (auto &P : ThunkedSections)
14361501 AddressesChanged |= P.second->assignOffsets();
14371502
deps/lld/ELF/Relocations.h+30-9
......@@ -33,16 +33,28 @@ enum RelExpr {
3333 R_INVALID,
3434 R_ABS,
3535 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,
3645 R_ARM_SBREL,
3746 R_GOT,
47 // The expression is used for IFUNC support. Evaluates to GOT entry,
48 // containing redirection to the IPLT.
49 R_GOT_PLT,
3850 R_GOTONLY_PC,
3951 R_GOTONLY_PC_FROM_END,
4052 R_GOTREL,
4153 R_GOTREL_FROM_END,
4254 R_GOT_FROM_END,
4355 R_GOT_OFF,
44 R_GOT_PAGE_PC,
4556 R_GOT_PC,
57 R_HEXAGON_GOT,
4658 R_HINT,
4759 R_MIPS_GOTREL,
4860 R_MIPS_GOT_GP,
......@@ -54,10 +66,8 @@ enum RelExpr {
5466 R_MIPS_TLSLD,
5567 R_NEG_TLS,
5668 R_NONE,
57 R_PAGE_PC,
5869 R_PC,
5970 R_PLT,
60 R_PLT_PAGE_PC,
6171 R_PLT_PC,
6272 R_PPC_CALL,
6373 R_PPC_CALL_PLT,
......@@ -68,20 +78,20 @@ enum RelExpr {
6878 R_RELAX_TLS_GD_TO_IE_ABS,
6979 R_RELAX_TLS_GD_TO_IE_END,
7080 R_RELAX_TLS_GD_TO_IE_GOT_OFF,
71 R_RELAX_TLS_GD_TO_IE_PAGE_PC,
7281 R_RELAX_TLS_GD_TO_LE,
7382 R_RELAX_TLS_GD_TO_LE_NEG,
7483 R_RELAX_TLS_IE_TO_LE,
7584 R_RELAX_TLS_LD_TO_LE,
7685 R_RELAX_TLS_LD_TO_LE_ABS,
86 R_RISCV_PC_INDIRECT,
7787 R_SIZE,
7888 R_TLS,
7989 R_TLSDESC,
8090 R_TLSDESC_CALL,
81 R_TLSDESC_PAGE,
8291 R_TLSGD_GOT,
8392 R_TLSGD_GOT_FROM_END,
8493 R_TLSGD_PC,
94 R_TLSIE_HINT,
8595 R_TLSLD_GOT,
8696 R_TLSLD_GOT_FROM_END,
8797 R_TLSLD_GOT_OFF,
......@@ -128,6 +138,21 @@ struct Relocation {
128138 Symbol *Sym;
129139};
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
131156template <class ELFT> void scanRelocations(InputSectionBase &);
132157
133158class ThunkSection;
......@@ -155,10 +180,6 @@ private:
155180
156181 void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
157182
158 void forEachInputSectionDescription(
159 ArrayRef<OutputSection *> OutputSections,
160 llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn);
161
162183 std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src);
163184
164185 ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
deps/lld/ELF/ScriptLexer.cpp+9
......@@ -244,6 +244,15 @@ StringRef ScriptLexer::peek() {
244244 return Tok;
245245}
246246
247StringRef ScriptLexer::peek2() {
248 skip();
249 StringRef Tok = next();
250 if (errorCount())
251 return "";
252 Pos = Pos - 2;
253 return Tok;
254}
255
247256bool ScriptLexer::consume(StringRef Tok) {
248257 if (peek() == Tok) {
249258 skip();
deps/lld/ELF/ScriptLexer.h+1
......@@ -29,6 +29,7 @@ public:
2929 bool atEOF();
3030 StringRef next();
3131 StringRef peek();
32 StringRef peek2();
3233 void skip();
3334 bool consume(StringRef Tok);
3435 void expect(StringRef Expect);
deps/lld/ELF/ScriptParser.cpp+108-36
......@@ -72,13 +72,15 @@ private:
7272 void readRegionAlias();
7373 void readSearchDir();
7474 void readSections();
75 void readTarget();
7576 void readVersion();
7677 void readVersionScriptCommand();
7778
7879 SymbolAssignment *readSymbolAssignment(StringRef Name);
7980 ByteCommand *readByteCommand(StringRef Tok);
80 uint32_t readFill();
81 uint32_t parseFill(StringRef Tok);
81 std::array<uint8_t, 4> readFill();
82 std::array<uint8_t, 4> parseFill(StringRef Tok);
83 bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
8284 void readSectionAddressType(OutputSection *Cmd);
8385 OutputSection *readOverlaySectionDescription();
8486 OutputSection *readOutputSectionDescription(StringRef OutSec);
......@@ -255,6 +257,8 @@ void ScriptParser::readLinkerScript() {
255257 readSearchDir();
256258 } else if (Tok == "SECTIONS") {
257259 readSections();
260 } else if (Tok == "TARGET") {
261 readTarget();
258262 } else if (Tok == "VERSION") {
259263 readVersion();
260264 } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
......@@ -266,6 +270,8 @@ void ScriptParser::readLinkerScript() {
266270}
267271
268272void ScriptParser::readDefsym(StringRef Name) {
273 if (errorCount())
274 return;
269275 Expr E = readExpr();
270276 if (!atEOF())
271277 setError("EOF expected, but got " + next());
......@@ -378,10 +384,42 @@ void ScriptParser::readOutputArch() {
378384 skip();
379385}
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.
381409void ScriptParser::readOutputFormat() {
382 // Error checking only for now.
383410 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
385423 if (consume(")"))
386424 return;
387425 expect(",");
......@@ -497,6 +535,9 @@ void ScriptParser::readSections() {
497535 for (BaseCommand *Cmd : readOverlay())
498536 V.push_back(Cmd);
499537 continue;
538 } else if (Tok == "INCLUDE") {
539 readInclude();
540 continue;
500541 }
501542
502543 if (BaseCommand *Cmd = readAssignment(Tok))
......@@ -522,6 +563,23 @@ void ScriptParser::readSections() {
522563 V.end());
523564}
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
525583static int precedence(StringRef Op) {
526584 return StringSwitch<int>(Op)
527585 .Cases("*", "/", "%", 8)
......@@ -672,13 +730,33 @@ Expr ScriptParser::readAssert() {
672730// alias for =fillexp section attribute, which is different from
673731// what GNU linkers do.
674732// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
675uint32_t ScriptParser::readFill() {
733std::array<uint8_t, 4> ScriptParser::readFill() {
676734 expect("(");
677 uint32_t V = parseFill(next());
735 std::array<uint8_t, 4> V = parseFill(next());
678736 expect(")");
679737 return V;
680738}
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
682760// Reads an expression and/or the special directive for an output
683761// section definition. Directive is one of following: "(NOLOAD)",
684762// "(COPY)", "(INFO)" or "(OVERLAY)".
......@@ -691,28 +769,12 @@ uint32_t ScriptParser::readFill() {
691769// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
692770// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
693771void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
694 if (consume("(")) {
695 if (consume("NOLOAD")) {
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 }
772 if (readSectionDirective(Cmd, peek(), peek2()))
773 return;
710774
711 if (consume("(")) {
712 expect("NOLOAD");
713 expect(")");
714 Cmd->Noload = true;
715 }
775 Cmd->AddrExpr = readExpr();
776 if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
777 setError("unknown section directive: " + peek2());
716778}
717779
718780static Expr checkAlignment(Expr E, std::string &Loc) {
......@@ -778,10 +840,17 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
778840 Cmd->Filler = readFill();
779841 } else if (Tok == "SORT") {
780842 readSort();
843 } else if (Tok == "INCLUDE") {
844 readInclude();
781845 } else if (peek() == "(") {
782846 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
783847 } 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);
785854 }
786855 }
787856
......@@ -818,13 +887,13 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
818887// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
819888// size, while ld.gold always handles it as a 32-bit big-endian number.
820889// 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) {
822891 uint32_t V = 0;
823892 if (!to_integer(Tok, V))
824893 setError("invalid filler expression: " + Tok);
825894
826 uint32_t Buf;
827 write32be(&Buf, V);
895 std::array<uint8_t, 4> Buf;
896 write32be(Buf.data(), V);
828897 return Buf;
829898}
830899
......@@ -1404,7 +1473,11 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
14041473void ScriptParser::readMemory() {
14051474 expect("{");
14061475 while (!errorCount() && !consume("}")) {
1407 StringRef Name = next();
1476 StringRef Tok = next();
1477 if (Tok == "INCLUDE") {
1478 readInclude();
1479 continue;
1480 }
14081481
14091482 uint32_t Flags = 0;
14101483 uint32_t NegFlags = 0;
......@@ -1419,10 +1492,9 @@ void ScriptParser::readMemory() {
14191492 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
14201493
14211494 // Add the memory region to the region map.
1422 MemoryRegion *MR =
1423 make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags);
1424 if (!Script->MemoryRegions.insert({Name, MR}).second)
1425 setError("region '" + Name + "' already defined");
1495 MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
1496 if (!Script->MemoryRegions.insert({Tok, MR}).second)
1497 setError("region '" + Tok + "' already defined");
14261498 }
14271499}
14281500
deps/lld/ELF/SymbolTable.cpp+92-158
......@@ -94,8 +94,20 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
9494 if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
9595 // DSOs are uniquified not by filename but by soname.
9696 F->parseSoName();
97 if (errorCount() || !SoNames.insert(F->SoName).second)
97 if (errorCount())
9898 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
99111 SharedFiles.push_back(F);
100112 F->parseRest();
101113 return;
......@@ -139,77 +151,27 @@ template <class ELFT> void SymbolTable::addCombinedLTOObject() {
139151 }
140152}
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
149154// Set a flag for --trace-symbol so that we can print out a log message
150155// if a new symbol with the same name is inserted into the symbol table.
151156void SymbolTable::trace(StringRef Name) {
152157 SymMap.insert({CachedHashStringRef(Name), -1});
153158}
154159
155// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
156// Used to implement --wrap.
157template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
158 Symbol *Sym = find(Name);
159 if (!Sym)
160 return;
161
162 // Do not wrap the same symbol twice.
163 for (const WrappedSymbol &S : WrappedSymbols)
164 if (S.Sym == Sym)
165 return;
160void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
161 // Swap symbols as instructed by -wrap.
162 int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
163 int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
164 int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
166165
167 Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
168 Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
169 WrappedSymbols.push_back({Sym, Real, Wrap});
166 Idx2 = Idx1;
167 Idx1 = Idx3;
170168
171 // We want to tell LTO not to inline symbols to be overwritten
172 // because LTO doesn't know the final symbol contents after renaming.
173 Real->CanInline = false;
174 Sym->CanInline = false;
175
176 // Tell LTO not to eliminate these symbols.
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 }
169 // Now renaming is complete. No one refers Real symbol. We could leave
170 // Real as-is, but if Real is written to the symbol table, that may
171 // contain irrelevant values. So, we copy all values from Sym to Real.
172 StringRef S = Real->getName();
173 memcpy(Real, Sym, sizeof(SymbolUnion));
174 Real->setName(S);
213175}
214176
215177static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
......@@ -221,7 +183,7 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
221183}
222184
223185// 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) {
225187 // <name>@@<version> means the symbol is the default version. In that
226188 // case <name>@@<version> will be used to resolve references to <name>.
227189 //
......@@ -239,34 +201,34 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
239201
240202 if (SymIndex == -1) {
241203 SymIndex = SymVector.size();
242 IsNew = Traced = true;
204 IsNew = true;
205 Traced = true;
243206 }
244207
245 Symbol *Sym;
246 if (IsNew) {
247 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
248 Sym->Visibility = STV_DEFAULT;
249 Sym->IsUsedInRegularObj = false;
250 Sym->ExportDynamic = false;
251 Sym->CanInline = true;
252 Sym->Traced = Traced;
253 Sym->VersionId = Config->DefaultSymbolVersion;
254 SymVector.push_back(Sym);
255 } else {
256 Sym = SymVector[SymIndex];
257 }
258 return {Sym, IsNew};
208 if (!IsNew)
209 return {SymVector[SymIndex], false};
210
211 auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
212 Sym->SymbolKind = Symbol::PlaceholderKind;
213 Sym->Visibility = STV_DEFAULT;
214 Sym->IsUsedInRegularObj = false;
215 Sym->ExportDynamic = false;
216 Sym->CanInline = true;
217 Sym->Traced = Traced;
218 Sym->VersionId = Config->DefaultSymbolVersion;
219 SymVector.push_back(Sym);
220 return {Sym, true};
259221}
260222
261223// Find an existing symbol or create and insert a new one, then apply the given
262224// attributes.
263std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
225std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
264226 uint8_t Visibility,
265227 bool CanOmitFromDynSym,
266228 InputFile *File) {
267229 Symbol *S;
268230 bool WasInserted;
269 std::tie(S, WasInserted) = insert(Name);
231 std::tie(S, WasInserted) = insertName(Name);
270232
271233 // Merge in the new symbol's visibility.
272234 S->Visibility = getMinVisibility(S->Visibility, Visibility);
......@@ -277,21 +239,9 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
277239 if (!File || File->kind() == InputFile::ObjKind)
278240 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
286242 return {S, WasInserted};
287243}
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
295245static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
296246
297247template <class ELFT>
......@@ -301,8 +251,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
301251 Symbol *S;
302252 bool WasInserted;
303253 uint8_t Visibility = getVisibility(StOther);
304 std::tie(S, WasInserted) =
305 insert(Name, Type, Visibility, CanOmitFromDynSym, File);
254 std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
306255
307256 // An undefined symbol with non default visibility must be satisfied
308257 // in the same DSO.
......@@ -314,10 +263,6 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
314263 if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
315264 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
321266 if (S->isLazy()) {
322267 // An undefined weak will not fetch archive members. See comment on Lazy in
323268 // Symbols.h for the details.
......@@ -450,7 +395,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
450395 InputFile &File) {
451396 Symbol *S;
452397 bool WasInserted;
453 std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
398 std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
454399 /*CanOmitFromDynSym*/ false, &File);
455400
456401 int Cmp = compareDefined(S, WasInserted, Binding, N);
......@@ -487,12 +432,6 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
487432 return S;
488433}
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
496435static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
497436 InputSectionBase *ErrSec, uint64_t ErrOffset) {
498437 if (Config->AllowMultipleDefinition)
......@@ -500,7 +439,8 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
500439
501440 Defined *D = cast<Defined>(Sym);
502441 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));
504444 return;
505445 }
506446
......@@ -527,12 +467,12 @@ static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
527467 error(Msg);
528468}
529469
530Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
531 uint64_t Value, uint64_t Size, uint8_t Binding,
532 SectionBase *Section, InputFile *File) {
470Defined *SymbolTable::addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
471 uint64_t Value, uint64_t Size, uint8_t Binding,
472 SectionBase *Section, InputFile *File) {
533473 Symbol *S;
534474 bool WasInserted;
535 std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
475 std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
536476 /*CanOmitFromDynSym*/ false, File);
537477 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
538478 Value, Name);
......@@ -542,7 +482,7 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
542482 else if (Cmp == 0)
543483 reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
544484 Value);
545 return S;
485 return cast<Defined>(S);
546486}
547487
548488template <typename ELFT>
......@@ -554,7 +494,7 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
554494 // unchanged.
555495 Symbol *S;
556496 bool WasInserted;
557 std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
497 std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
558498 /*CanOmitFromDynSym*/ true, &File);
559499 // Make sure we preempt DSO symbols with default visibility.
560500 if (Sym.getVisibility() == STV_DEFAULT)
......@@ -562,19 +502,16 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
562502
563503 // An undefined symbol with non default visibility must be satisfied
564504 // in the same DSO.
565 if (WasInserted ||
566 ((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) {
567 uint8_t Binding = S->Binding;
568 bool WasUndefined = S->isUndefined();
569 replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
505 auto Replace = [&](uint8_t Binding) {
506 replaceSymbol<SharedSymbol>(S, File, Name, Binding, Sym.st_other,
570507 Sym.getType(), Sym.st_value, Sym.st_size,
571508 Alignment, VerdefIndex);
572 if (!WasInserted) {
573 S->Binding = Binding;
574 if (!S->isWeak() && !Config->GcSections && WasUndefined)
575 File.IsNeeded = true;
576 }
577 }
509 };
510
511 if (WasInserted)
512 Replace(Sym.getBinding());
513 else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
514 Replace(S->Binding);
578515}
579516
580517Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
......@@ -583,13 +520,13 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
583520 Symbol *S;
584521 bool WasInserted;
585522 std::tie(S, WasInserted) =
586 insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);
523 insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
587524 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
588525 /*IsAbs*/ false, /*Value*/ 0, Name);
589526 if (Cmp > 0)
590527 replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
591528 else if (Cmp == 0)
592 reportDuplicate(S, &F);
529 reportDuplicate(S, &F, nullptr, 0);
593530 return S;
594531}
595532
......@@ -602,18 +539,14 @@ Symbol *SymbolTable::find(StringRef Name) {
602539 return SymVector[It->second];
603540}
604541
605// This is used to handle lazy symbols. May replace existent
606// symbol with lazy version or request to Fetch it.
607template <class ELFT, typename LazyT, typename... ArgT>
608static void replaceOrFetchLazy(StringRef Name, InputFile &File,
609 llvm::function_ref<InputFile *()> Fetch,
610 ArgT &&... Arg) {
542template <class ELFT>
543void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
544 const object::Archive::Symbol Sym) {
611545 Symbol *S;
612546 bool WasInserted;
613 std::tie(S, WasInserted) = Symtab->insert(Name);
547 std::tie(S, WasInserted) = insertName(Name);
614548 if (WasInserted) {
615 replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
616 std::forward<ArgT>(Arg)...);
549 replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
617550 return;
618551 }
619552 if (!S->isUndefined())
......@@ -622,26 +555,37 @@ static void replaceOrFetchLazy(StringRef Name, InputFile &File,
622555 // An undefined weak will not fetch archive members. See comment on Lazy in
623556 // Symbols.h for the details.
624557 if (S->isWeak()) {
625 replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
558 replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
626559 S->Binding = STB_WEAK;
627560 return;
628561 }
629562
630 if (InputFile *F = Fetch())
631 Symtab->addFile<ELFT>(F);
563 if (InputFile *F = File.fetch(Sym))
564 addFile<ELFT>(F);
632565}
633566
634567template <class ELFT>
635void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F,
636 const object::Archive::Symbol Sym) {
637 replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
638 Sym);
639}
568void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
569 Symbol *S;
570 bool WasInserted;
571 std::tie(S, WasInserted) = insertName(Name);
572 if (WasInserted) {
573 replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
574 return;
575 }
576 if (!S->isUndefined())
577 return;
640578
641template <class ELFT>
642void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
643 replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },
644 Name);
579 // An undefined weak will not fetch archive members. See comment on Lazy in
580 // Symbols.h for the details.
581 if (S->isWeak()) {
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);
645589}
646590
647591template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
......@@ -822,16 +766,6 @@ template void SymbolTable::addFile<ELF32BE>(InputFile *);
822766template void SymbolTable::addFile<ELF64LE>(InputFile *);
823767template 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
835769template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
836770 uint8_t, bool, InputFile *);
837771template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
deps/lld/ELF/SymbolTable.h+10-24
......@@ -37,22 +37,17 @@ class SymbolTable {
3737public:
3838 template <class ELFT> void addFile(InputFile *File);
3939 template <class ELFT> void addCombinedLTOObject();
40 template <class ELFT> void addSymbolWrap(StringRef Name);
41 void applySymbolWrap();
40 void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
4241
4342 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);
5044 template <class ELFT>
5145 Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
5246 uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
53 Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
54 uint64_t Value, uint64_t Size, uint8_t Binding,
55 SectionBase *Section, InputFile *File);
47
48 Defined *addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
49 uint64_t Value, uint64_t Size, uint8_t Binding,
50 SectionBase *Section, InputFile *File);
5651
5752 template <class ELFT>
5853 void addShared(StringRef Name, SharedFile<ELFT> &F,
......@@ -72,10 +67,8 @@ public:
7267 uint8_t Binding, uint8_t StOther, uint8_t Type,
7368 InputFile &File);
7469
75 std::pair<Symbol *, bool> insert(StringRef Name);
76 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
77 uint8_t Visibility, bool CanOmitFromDynSym,
78 InputFile *File);
70 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
71 bool CanOmitFromDynSym, InputFile *File);
7972
8073 template <class ELFT> void fetchLazy(Symbol *Sym);
8174
......@@ -88,6 +81,8 @@ public:
8881 void handleDynamicList();
8982
9083private:
84 std::pair<Symbol *, bool> insertName(StringRef Name);
85
9186 std::vector<Symbol *> findByVersion(SymbolVersion Ver);
9287 std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
9388
......@@ -113,7 +108,7 @@ private:
113108 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
114109
115110 // 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
118113 // A map from demangled symbol names to their symbol objects.
119114 // This mapping is 1:N because two symbols with different versions
......@@ -121,15 +116,6 @@ private:
121116 // directive in version scripts.
122117 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
133119 // For LTO.
134120 std::unique_ptr<BitcodeCompiler> LTO;
135121};
deps/lld/ELF/Symbols.cpp+46-14
......@@ -38,6 +38,7 @@ Defined *ElfSym::GlobalOffsetTable;
3838Defined *ElfSym::MipsGp;
3939Defined *ElfSym::MipsGpDisp;
4040Defined *ElfSym::MipsLocalGp;
41Defined *ElfSym::RelaIpltStart;
4142Defined *ElfSym::RelaIpltEnd;
4243
4344static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
......@@ -90,10 +91,15 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
9091 uint64_t VA = IS->getVA(Offset);
9192
9293 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)
94100 fatal(toString(D.File) +
95101 " 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;
97103 }
98104 return VA;
99105 }
......@@ -102,7 +108,10 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
102108 return 0;
103109 case Symbol::LazyArchiveKind:
104110 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");
106115 }
107116 llvm_unreachable("invalid symbol kind");
108117}
......@@ -112,7 +121,7 @@ uint64_t Symbol::getVA(int64_t Addend) const {
112121 return OutVA + Addend;
113122}
114123
115uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); }
124uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
116125
117126uint64_t Symbol::getGotOffset() const {
118127 return GotIndex * Target->GotEntrySize;
......@@ -120,8 +129,8 @@ uint64_t Symbol::getGotOffset() const {
120129
121130uint64_t Symbol::getGotPltVA() const {
122131 if (this->IsInIgot)
123 return InX::IgotPlt->getVA() + getGotPltOffset();
124 return InX::GotPlt->getVA() + getGotPltOffset();
132 return In.IgotPlt->getVA() + getGotPltOffset();
133 return In.GotPlt->getVA() + getGotPltOffset();
125134}
126135
127136uint64_t Symbol::getGotPltOffset() const {
......@@ -130,15 +139,20 @@ uint64_t Symbol::getGotPltOffset() const {
130139 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
131140}
132141
142uint64_t Symbol::getPPC64LongBranchOffset() const {
143 assert(PPC64BranchltIndex != 0xffff);
144 return PPC64BranchltIndex * Target->GotPltEntrySize;
145}
146
133147uint64_t Symbol::getPltVA() const {
134 if (this->IsInIplt)
135 return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize;
136 return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex);
148 PltSection *Plt = IsInIplt ? In.Iplt : In.Plt;
149 return Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;
137150}
138151
139uint64_t Symbol::getPltOffset() const {
140 assert(!this->IsInIplt);
141 return Target->getPltEntryOffset(PltIndex);
152uint64_t Symbol::getPPC64LongBranchTableVA() const {
153 assert(PPC64BranchltIndex != 0xffff);
154 return In.PPC64LongBranchTarget->getVA() +
155 PPC64BranchltIndex * Target->GotPltEntrySize;
142156}
143157
144158uint64_t Symbol::getSize() const {
......@@ -204,12 +218,21 @@ void Symbol::parseSymbolVersion() {
204218
205219InputFile *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
207230uint8_t Symbol::computeBinding() const {
208231 if (Config->Relocatable)
209232 return Binding;
210233 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
211234 return STB_LOCAL;
212 if (VersionId == VER_NDX_LOCAL && isDefined())
235 if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
213236 return STB_LOCAL;
214237 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
215238 return STB_GLOBAL;
......@@ -243,10 +266,19 @@ void elf::printTraceSymbol(Symbol *Sym) {
243266 message(toString(Sym->File) + S + Sym->getName());
244267}
245268
246void elf::warnUnorderableSymbol(const Symbol *Sym) {
269void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
247270 if (!Config->WarnSymbolOrdering)
248271 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
250282 const InputFile *File = Sym->File;
251283 auto *D = dyn_cast<Defined>(Sym);
252284
deps/lld/ELF/Symbols.h+51-15
......@@ -21,6 +21,14 @@
2121#include "llvm/Object/ELF.h"
2222
2323namespace lld {
24namespace elf {
25class Symbol;
26class InputFile;
27} // namespace elf
28
29std::string toString(const elf::Symbol &);
30std::string toString(const elf::InputFile *);
31
2432namespace elf {
2533
2634class ArchiveFile;
......@@ -50,6 +58,7 @@ struct StringRefZ {
5058class Symbol {
5159public:
5260 enum Kind {
61 PlaceholderKind,
5362 DefinedKind,
5463 SharedKind,
5564 UndefinedKind,
......@@ -70,6 +79,7 @@ public:
7079 uint32_t DynsymIndex = 0;
7180 uint32_t GotIndex = -1;
7281 uint32_t PltIndex = -1;
82
7383 uint32_t GlobalDynIndex = -1;
7484
7585 // This field is a index to the symbol's version definition.
......@@ -78,6 +88,9 @@ public:
7888 // Version definition index.
7989 uint16_t VersionId;
8090
91 // An index into the .branch_lt section on PPC64.
92 uint16_t PPC64BranchltIndex = -1;
93
8194 // Symbol binding. This is not overwritten by replaceSymbol to track
8295 // changes during resolution. In particular:
8396 // - An undefined weak is still weak when it resolves to a shared library.
......@@ -89,7 +102,7 @@ public:
89102 uint8_t Type; // symbol type
90103 uint8_t StOther; // st_other field value
91104
92 const uint8_t SymbolKind;
105 uint8_t SymbolKind;
93106
94107 // Symbol visibility. This is the computed minimum visibility of all
95108 // observed non-DSO symbols.
......@@ -128,8 +141,12 @@ public:
128141 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
129142 }
130143
131 // True if this is an undefined weak symbol.
132 bool isUndefWeak() const { return isWeak() && isUndefined(); }
144 // True if this is an undefined weak symbol. This only works once
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
134151 StringRef getName() const {
135152 if (NameSize == (uint32_t)-1)
......@@ -137,10 +154,16 @@ public:
137154 return {NameData, NameSize};
138155 }
139156
157 void setName(StringRef S) {
158 NameData = S.data();
159 NameSize = S.size();
160 }
161
140162 void parseSymbolVersion();
141163
142164 bool isInGot() const { return GotIndex != -1U; }
143165 bool isInPlt() const { return PltIndex != -1U; }
166 bool isInPPC64Branchlt() const { return PPC64BranchltIndex != 0xffff; }
144167
145168 uint64_t getVA(int64_t Addend = 0) const;
146169
......@@ -149,7 +172,8 @@ public:
149172 uint64_t getGotPltOffset() const;
150173 uint64_t getGotPltVA() const;
151174 uint64_t getPltVA() const;
152 uint64_t getPltOffset() const;
175 uint64_t getPPC64LongBranchTableVA() const;
176 uint64_t getPPC64LongBranchOffset() const;
153177 uint64_t getSize() const;
154178 OutputSection *getOutputSection() const;
155179
......@@ -159,7 +183,8 @@ protected:
159183 : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
160184 Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
161185 IsInIplt(false), IsInIgot(false), IsPreemptible(false),
162 Used(!Config->GcSections), NeedsTocRestore(false) {}
186 Used(!Config->GcSections), NeedsTocRestore(false),
187 ScriptDefined(false) {}
163188
164189public:
165190 // True the symbol should point to its PLT entry.
......@@ -182,12 +207,8 @@ public:
182207 // PPC64 toc pointer.
183208 unsigned NeedsTocRestore : 1;
184209
185 // The Type field may also have this value. It means that we have not yet seen
186 // a non-Lazy symbol with this name, so we don't know what its type is. The
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 };
210 // True if this symbol is defined by a linker script.
211 unsigned ScriptDefined : 1;
191212
192213 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
193214 bool isTls() const { return Type == llvm::ELF::STT_TLS; }
......@@ -286,6 +307,7 @@ public:
286307 static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
287308
288309 InputFile *fetch();
310 MemoryBufferRef getMemberBuffer();
289311
290312private:
291313 const llvm::object::Archive::Symbol Sym;
......@@ -330,7 +352,8 @@ struct ElfSym {
330352 static Defined *MipsGpDisp;
331353 static Defined *MipsLocalGp;
332354
333 // __rela_iplt_end or __rel_iplt_end
355 // __rel{,a}_iplt_{start,end} symbols.
356 static Defined *RelaIpltStart;
334357 static Defined *RelaIpltEnd;
335358};
336359
......@@ -349,6 +372,8 @@ void printTraceSymbol(Symbol *Sym);
349372
350373template <typename T, typename... ArgT>
351374void replaceSymbol(Symbol *S, ArgT &&... Arg) {
375 using llvm::ELF::STT_TLS;
376
352377 static_assert(std::is_trivially_destructible<T>(),
353378 "Symbol types must be trivially destructible");
354379 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
......@@ -367,6 +392,19 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
367392 S->ExportDynamic = Sym.ExportDynamic;
368393 S->CanInline = Sym.CanInline;
369394 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
371409 // Print out a log message if --trace-symbol was specified.
372410 // This is for debugging.
......@@ -374,10 +412,8 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
374412 printTraceSymbol(S);
375413}
376414
377void warnUnorderableSymbol(const Symbol *Sym);
415void maybeWarnUnorderableSymbol(const Symbol *Sym);
378416} // namespace elf
379
380std::string toString(const elf::Symbol &B);
381417} // namespace lld
382418
383419#endif
deps/lld/ELF/SyntheticSections.cpp+290-214
......@@ -30,10 +30,11 @@
3030#include "lld/Common/Threads.h"
3131#include "lld/Common/Version.h"
3232#include "llvm/ADT/SetOperations.h"
33#include "llvm/ADT/StringExtras.h"
3334#include "llvm/BinaryFormat/Dwarf.h"
3435#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
35#include "llvm/Object/Decompressor.h"
3636#include "llvm/Object/ELFObjectFile.h"
37#include "llvm/Support/Compression.h"
3738#include "llvm/Support/Endian.h"
3839#include "llvm/Support/LEB128.h"
3940#include "llvm/Support/MD5.h"
......@@ -104,7 +105,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
104105 Create = true;
105106
106107 std::string Filename = toString(Sec->File);
107 const size_t Size = Sec->Data.size();
108 const size_t Size = Sec->data().size();
108109 // Older version of BFD (such as the default FreeBSD linker) concatenate
109110 // .MIPS.abiflags instead of merging. To allow for this case (or potential
110111 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
......@@ -113,7 +114,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
113114 Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
114115 return nullptr;
115116 }
116 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->Data.data());
117 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
117118 if (S->version != 0) {
118119 error(Filename + ": unexpected .MIPS.abiflags version " +
119120 Twine(S->version));
......@@ -153,7 +154,7 @@ template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
153154 Options->size = getSize();
154155
155156 if (!Config->Relocatable)
156 Reginfo.ri_gp_value = InX::MipsGot->getGp();
157 Reginfo.ri_gp_value = In.MipsGot->getGp();
157158 memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
158159}
159160
......@@ -176,7 +177,7 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
176177 Sec->Live = false;
177178
178179 std::string Filename = toString(Sec->File);
179 ArrayRef<uint8_t> D = Sec->Data;
180 ArrayRef<uint8_t> D = Sec->data();
180181
181182 while (!D.empty()) {
182183 if (D.size() < sizeof(Elf_Mips_Options)) {
......@@ -210,7 +211,7 @@ MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
210211
211212template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
212213 if (!Config->Relocatable)
213 Reginfo.ri_gp_value = InX::MipsGot->getGp();
214 Reginfo.ri_gp_value = In.MipsGot->getGp();
214215 memcpy(Buf, &Reginfo, sizeof(Reginfo));
215216}
216217
......@@ -232,12 +233,12 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
232233 for (InputSectionBase *Sec : Sections) {
233234 Sec->Live = false;
234235
235 if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) {
236 if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
236237 error(toString(Sec->File) + ": invalid size of .reginfo section");
237238 return nullptr;
238239 }
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());
241242 Reginfo.ri_gprmask |= R->ri_gprmask;
242243 Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
243244 };
......@@ -260,8 +261,8 @@ Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
260261 uint64_t Size, InputSectionBase &Section) {
261262 auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
262263 Value, Size, &Section);
263 if (InX::SymTab)
264 InX::SymTab->addSymbol(S);
264 if (In.SymTab)
265 In.SymTab->addSymbol(S);
265266 return S;
266267}
267268
......@@ -502,7 +503,7 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
502503 uint8_t *Buf = getParent()->Loc + OutSecOff;
503504 std::vector<FdeData> Ret;
504505
505 uint64_t VA = InX::EhFrameHdr->getVA();
506 uint64_t VA = In.EhFrameHdr->getVA();
506507 for (CieRecord *Rec : CieRecords) {
507508 uint8_t Enc = getFdeEncoding(Rec->Cie);
508509 for (EhSectionPiece *Fde : Rec->Fdes) {
......@@ -937,7 +938,7 @@ template <class ELFT> void MipsGotSection::build() {
937938 Symbol *S = P.first;
938939 uint64_t Offset = P.second * Config->Wordsize;
939940 if (S->IsPreemptible)
940 InX::RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
941 In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
941942 }
942943 for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
943944 Symbol *S = P.first;
......@@ -945,7 +946,7 @@ template <class ELFT> void MipsGotSection::build() {
945946 if (S == nullptr) {
946947 if (!Config->Pic)
947948 continue;
948 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
949 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
949950 } else {
950951 // When building a shared library we still need a dynamic relocation
951952 // for the module index. Therefore only checking for
......@@ -953,13 +954,13 @@ template <class ELFT> void MipsGotSection::build() {
953954 // thread-locals that have been marked as local through a linker script)
954955 if (!S->IsPreemptible && !Config->Pic)
955956 continue;
956 InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
957 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
957958 // However, we can skip writing the TLS offset reloc for non-preemptible
958959 // symbols since it is known even in shared libraries
959960 if (!S->IsPreemptible)
960961 continue;
961962 Offset += Config->Wordsize;
962 InX::RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
963 In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
963964 }
964965 }
965966
......@@ -971,7 +972,7 @@ template <class ELFT> void MipsGotSection::build() {
971972 // Dynamic relocations for "global" entries.
972973 for (const std::pair<Symbol *, size_t> &P : Got.Global) {
973974 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);
975976 }
976977 if (!Config->Pic)
977978 continue;
......@@ -981,14 +982,14 @@ template <class ELFT> void MipsGotSection::build() {
981982 size_t PageCount = L.second.Count;
982983 for (size_t PI = 0; PI < PageCount; ++PI) {
983984 uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
984 InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
985 int64_t(PI * 0x10000)});
985 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
986 int64_t(PI * 0x10000)});
986987 }
987988 }
988989 for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
989990 uint64_t Offset = P.second * Config->Wordsize;
990 InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
991 P.first.first, P.first.second});
991 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
992 P.first.first, P.first.second});
992993 }
993994 }
994995}
......@@ -1200,21 +1201,21 @@ DynamicSection<ELFT>::DynamicSection()
12001201 // Add strings to .dynstr early so that .dynstr's size will be
12011202 // fixed early.
12021203 for (StringRef S : Config->FilterList)
1203 addInt(DT_FILTER, InX::DynStrTab->addString(S));
1204 addInt(DT_FILTER, In.DynStrTab->addString(S));
12041205 for (StringRef S : Config->AuxiliaryList)
1205 addInt(DT_AUXILIARY, InX::DynStrTab->addString(S));
1206 addInt(DT_AUXILIARY, In.DynStrTab->addString(S));
12061207
12071208 if (!Config->Rpath.empty())
12081209 addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
1209 InX::DynStrTab->addString(Config->Rpath));
1210 In.DynStrTab->addString(Config->Rpath));
12101211
12111212 for (InputFile *File : SharedFiles) {
12121213 SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
12131214 if (F->IsNeeded)
1214 addInt(DT_NEEDED, InX::DynStrTab->addString(F->SoName));
1215 addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
12151216 }
12161217 if (!Config->SoName.empty())
1217 addInt(DT_SONAME, InX::DynStrTab->addString(Config->SoName));
1218 addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
12181219}
12191220
12201221template <class ELFT>
......@@ -1254,18 +1255,33 @@ void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
12541255 Entries.push_back({Tag, [=] { return Sym->getVA(); }});
12551256}
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
12571270// Add remaining entries to complete .dynamic contents.
12581271template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1259 if (this->Size)
1260 return; // Already finalized.
1261
12621272 // Set DT_FLAGS and DT_FLAGS_1.
12631273 uint32_t DtFlags = 0;
12641274 uint32_t DtFlags1 = 0;
12651275 if (Config->Bsymbolic)
12661276 DtFlags |= DF_SYMBOLIC;
1277 if (Config->ZGlobal)
1278 DtFlags1 |= DF_1_GLOBAL;
12671279 if (Config->ZInitfirst)
12681280 DtFlags1 |= DF_1_INITFIRST;
1281 if (Config->ZInterpose)
1282 DtFlags1 |= DF_1_INTERPOSE;
1283 if (Config->ZNodefaultlib)
1284 DtFlags1 |= DF_1_NODEFLIB;
12691285 if (Config->ZNodelete)
12701286 DtFlags1 |= DF_1_NODELETE;
12711287 if (Config->ZNodlopen)
......@@ -1297,10 +1313,12 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
12971313 if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
12981314 addInt(DT_DEBUG, 0);
12991315
1300 this->Link = InX::DynStrTab->getParent()->SectionIndex;
1301 if (!InX::RelaDyn->empty()) {
1302 addInSec(InX::RelaDyn->DynamicTag, InX::RelaDyn);
1303 addSize(InX::RelaDyn->SizeDynamicTag, InX::RelaDyn->getParent());
1316 if (OutputSection *Sec = In.DynStrTab->getParent())
1317 this->Link = Sec->SectionIndex;
1318
1319 if (!In.RelaDyn->empty()) {
1320 addInSec(In.RelaDyn->DynamicTag, In.RelaDyn);
1321 addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent());
13041322
13051323 bool IsRela = Config->IsRela;
13061324 addInt(IsRela ? DT_RELAENT : DT_RELENT,
......@@ -1310,16 +1328,16 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
13101328 // The problem is in the tight relation between dynamic
13111329 // relocations and GOT. So do not emit this tag on MIPS.
13121330 if (Config->EMachine != EM_MIPS) {
1313 size_t NumRelativeRels = InX::RelaDyn->getRelativeRelocCount();
1331 size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount();
13141332 if (Config->ZCombreloc && NumRelativeRels)
13151333 addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
13161334 }
13171335 }
1318 if (InX::RelrDyn && !InX::RelrDyn->Relocs.empty()) {
1336 if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) {
13191337 addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
1320 InX::RelrDyn);
1338 In.RelrDyn);
13211339 addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
1322 InX::RelrDyn->getParent());
1340 In.RelrDyn->getParent());
13231341 addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
13241342 sizeof(Elf_Relr));
13251343 }
......@@ -1329,33 +1347,33 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
13291347 // as RelaIplt have. And we still want to emit proper dynamic tags for that
13301348 // case, so here we always use RelaPlt as marker for the begining of
13311349 // .rel[a].plt section.
1332 if (InX::RelaPlt->getParent()->Live) {
1333 addInSec(DT_JMPREL, InX::RelaPlt);
1334 addSize(DT_PLTRELSZ, InX::RelaPlt->getParent());
1350 if (In.RelaPlt->getParent()->Live) {
1351 addInSec(DT_JMPREL, In.RelaPlt);
1352 Entries.push_back({DT_PLTRELSZ, addPltRelSz});
13351353 switch (Config->EMachine) {
13361354 case EM_MIPS:
1337 addInSec(DT_MIPS_PLTGOT, InX::GotPlt);
1355 addInSec(DT_MIPS_PLTGOT, In.GotPlt);
13381356 break;
13391357 case EM_SPARCV9:
1340 addInSec(DT_PLTGOT, InX::Plt);
1358 addInSec(DT_PLTGOT, In.Plt);
13411359 break;
13421360 default:
1343 addInSec(DT_PLTGOT, InX::GotPlt);
1361 addInSec(DT_PLTGOT, In.GotPlt);
13441362 break;
13451363 }
13461364 addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
13471365 }
13481366
1349 addInSec(DT_SYMTAB, InX::DynSymTab);
1367 addInSec(DT_SYMTAB, In.DynSymTab);
13501368 addInt(DT_SYMENT, sizeof(Elf_Sym));
1351 addInSec(DT_STRTAB, InX::DynStrTab);
1352 addInt(DT_STRSZ, InX::DynStrTab->getSize());
1369 addInSec(DT_STRTAB, In.DynStrTab);
1370 addInt(DT_STRSZ, In.DynStrTab->getSize());
13531371 if (!Config->ZText)
13541372 addInt(DT_TEXTREL, 0);
1355 if (InX::GnuHashTab)
1356 addInSec(DT_GNU_HASH, InX::GnuHashTab);
1357 if (InX::HashTab)
1358 addInSec(DT_HASH, InX::HashTab);
1373 if (In.GnuHashTab)
1374 addInSec(DT_GNU_HASH, In.GnuHashTab);
1375 if (In.HashTab)
1376 addInSec(DT_HASH, In.HashTab);
13591377
13601378 if (Out::PreinitArray) {
13611379 addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
......@@ -1377,47 +1395,47 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
13771395 if (B->isDefined())
13781396 addSym(DT_FINI, B);
13791397
1380 bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
1381 if (HasVerNeed || In<ELFT>::VerDef)
1382 addInSec(DT_VERSYM, In<ELFT>::VerSym);
1383 if (In<ELFT>::VerDef) {
1384 addInSec(DT_VERDEF, In<ELFT>::VerDef);
1398 bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0;
1399 if (HasVerNeed || In.VerDef)
1400 addInSec(DT_VERSYM, InX<ELFT>::VerSym);
1401 if (In.VerDef) {
1402 addInSec(DT_VERDEF, In.VerDef);
13851403 addInt(DT_VERDEFNUM, getVerDefNum());
13861404 }
13871405 if (HasVerNeed) {
1388 addInSec(DT_VERNEED, In<ELFT>::VerNeed);
1389 addInt(DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum());
1406 addInSec(DT_VERNEED, InX<ELFT>::VerNeed);
1407 addInt(DT_VERNEEDNUM, InX<ELFT>::VerNeed->getNeedNum());
13901408 }
13911409
13921410 if (Config->EMachine == EM_MIPS) {
13931411 addInt(DT_MIPS_RLD_VERSION, 1);
13941412 addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
13951413 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())
14011419 addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
14021420 else
1403 addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols());
1404 addInSec(DT_PLTGOT, InX::MipsGot);
1405 if (InX::MipsRldMap) {
1421 addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols());
1422 addInSec(DT_PLTGOT, In.MipsGot);
1423 if (In.MipsRldMap) {
14061424 if (!Config->Pie)
1407 addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
1425 addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
14081426 // Store the offset to the .rld_map section
14091427 // 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);
14111429 }
14121430 }
14131431
14141432 // 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()) {
14161434 // The Glink tag points to 32 bytes before the first lazy symbol resolution
14171435 // stub, which starts directly after the header.
14181436 Entries.push_back({DT_PPC64_GLINK, [=] {
14191437 unsigned Offset = Target->PltHeaderSize - 32;
1420 return InX::Plt->getVA(0) + Offset;
1438 return In.Plt->getVA(0) + Offset;
14211439 }});
14221440 }
14231441
......@@ -1486,13 +1504,19 @@ void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
14861504}
14871505
14881506void RelocationBaseSection::finalizeContents() {
1489 // If all relocations are R_*_RELATIVE they don't refer to any
1490 // dynamic symbol and we don't need a dynamic symbol table. If that
1491 // is the case, just use 0 as the link.
1492 Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0;
1507 // When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
1508 // relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
1509 // case.
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.
1495 getParent()->Link = Link;
1516 if (In.RelaPlt == this)
1517 getParent()->Info = In.GotPlt->getParent()->SectionIndex;
1518 if (In.RelaIplt == this)
1519 getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
14961520}
14971521
14981522RelrBaseSection::RelrBaseSection()
......@@ -1621,10 +1645,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
16211645 NonRelatives.push_back(R);
16221646 }
16231647
1624 llvm::sort(Relatives.begin(), Relatives.end(),
1625 [](const Elf_Rel &A, const Elf_Rel &B) {
1626 return A.r_offset < B.r_offset;
1627 });
1648 llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
1649 return A.r_offset < B.r_offset;
1650 });
16281651
16291652 // Try to find groups of relative relocations which are spaced one word
16301653 // apart from one another. These generally correspond to vtable entries. The
......@@ -1702,10 +1725,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
17021725 }
17031726
17041727 // Finally the non-relative relocations.
1705 llvm::sort(NonRelatives.begin(), NonRelatives.end(),
1706 [](const Elf_Rela &A, const Elf_Rela &B) {
1707 return A.r_offset < B.r_offset;
1708 });
1728 llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
1729 return A.r_offset < B.r_offset;
1730 });
17091731 if (!NonRelatives.empty()) {
17101732 Add(NonRelatives.size());
17111733 Add(HasAddendIfRela);
......@@ -1720,6 +1742,11 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
17201742 }
17211743 }
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
17231750 // Returns whether the section size changed. We need to keep recomputing both
17241751 // section layout and the contents of this section until the size converges
17251752 // because changing this section's size can affect section layout, which in
......@@ -1843,10 +1870,13 @@ static bool sortMipsSymbols(const SymbolTableEntry &L,
18431870}
18441871
18451872void 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();
18491878 return;
1879 }
18501880
18511881 // If it is a .dynsym, there should be no local symbols, but we need
18521882 // to do a few things for the dynamic linker.
......@@ -1855,9 +1885,9 @@ void SymbolTableBaseSection::finalizeContents() {
18551885 // Because the first symbol entry is a null entry, 1 is the first.
18561886 getParent()->Info = 1;
18571887
1858 if (InX::GnuHashTab) {
1888 if (In.GnuHashTab) {
18591889 // NB: It also sorts Symbols to meet the GNU hash table requirements.
1860 InX::GnuHashTab->addSymbols(Symbols);
1890 In.GnuHashTab->addSymbols(Symbols);
18611891 } else if (Config->EMachine == EM_MIPS) {
18621892 std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
18631893 }
......@@ -1874,9 +1904,7 @@ void SymbolTableBaseSection::finalizeContents() {
18741904// Aside from above, we put local symbols in groups starting with the STT_FILE
18751905// symbol. That is convenient for purpose of identifying where are local symbols
18761906// coming from.
1877void SymbolTableBaseSection::postThunkContents() {
1878 assert(this->Type == SHT_SYMTAB);
1879
1907void SymbolTableBaseSection::sortSymTabSymbols() {
18801908 // Move all local symbols before global symbols.
18811909 auto E = std::stable_partition(
18821910 Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
......@@ -1948,7 +1976,8 @@ static uint32_t getSymSectionIndex(Symbol *Sym) {
19481976 if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
19491977 return SHN_UNDEF;
19501978 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;
19521981 return SHN_ABS;
19531982}
19541983
......@@ -2038,7 +2067,7 @@ void SymtabShndxSection::writeTo(uint8_t *Buf) {
20382067 // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
20392068 // we need to write actual index, otherwise, we must write SHN_UNDEF(0).
20402069 Buf += 4; // Ignore .symtab[0] entry.
2041 for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) {
2070 for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
20422071 if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
20432072 write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
20442073 Buf += 4;
......@@ -2059,11 +2088,11 @@ bool SymtabShndxSection::empty() const {
20592088}
20602089
20612090void SymtabShndxSection::finalizeContents() {
2062 getParent()->Link = InX::SymTab->getParent()->SectionIndex;
2091 getParent()->Link = In.SymTab->getParent()->SectionIndex;
20632092}
20642093
20652094size_t SymtabShndxSection::getSize() const {
2066 return InX::SymTab->getNumSymbols() * 4;
2095 return In.SymTab->getNumSymbols() * 4;
20672096}
20682097
20692098// .hash and .gnu.hash sections contain on-disk hash tables that map
......@@ -2102,7 +2131,8 @@ GnuHashTableSection::GnuHashTableSection()
21022131}
21032132
21042133void GnuHashTableSection::finalizeContents() {
2105 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
2134 if (OutputSection *Sec = In.DynSymTab->getParent())
2135 getParent()->Link = Sec->SectionIndex;
21062136
21072137 // Computes bloom filter size in word size. We want to allocate 12
21082138 // bits for each symbol. It must be a power of two.
......@@ -2127,7 +2157,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
21272157
21282158 // Write a header.
21292159 write32(Buf, NBuckets);
2130 write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size());
2160 write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size());
21312161 write32(Buf + 8, MaskWords);
21322162 write32(Buf + 12, Shift2);
21332163 Buf += 16;
......@@ -2148,6 +2178,8 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
21482178void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
21492179 unsigned C = Config->Is64 ? 64 : 32;
21502180 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].
21512183 size_t I = (Sym.Hash / C) & (MaskWords - 1);
21522184 uint64_t Val = readUint(Buf + I * Config->Wordsize);
21532185 Val |= uint64_t(1) << (Sym.Hash % C);
......@@ -2232,13 +2264,14 @@ HashTableSection::HashTableSection()
22322264}
22332265
22342266void HashTableSection::finalizeContents() {
2235 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
2267 if (OutputSection *Sec = In.DynSymTab->getParent())
2268 getParent()->Link = Sec->SectionIndex;
22362269
22372270 unsigned NumEntries = 2; // nbucket and nchain.
2238 NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
2271 NumEntries += In.DynSymTab->getNumSymbols(); // The chain entries.
22392272
22402273 // Create as many buckets as there are symbols.
2241 NumEntries += InX::DynSymTab->getNumSymbols();
2274 NumEntries += In.DynSymTab->getNumSymbols();
22422275 this->Size = NumEntries * 4;
22432276}
22442277
......@@ -2246,7 +2279,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {
22462279 // See comment in GnuHashTableSection::writeTo.
22472280 memset(Buf, 0, Size);
22482281
2249 unsigned NumSymbols = InX::DynSymTab->getNumSymbols();
2282 unsigned NumSymbols = In.DynSymTab->getNumSymbols();
22502283
22512284 uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
22522285 write32(P++, NumSymbols); // nbucket
......@@ -2255,7 +2288,7 @@ void HashTableSection::writeTo(uint8_t *Buf) {
22552288 uint32_t *Buckets = P;
22562289 uint32_t *Chains = P + NumSymbols;
22572290
2258 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
2291 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
22592292 Symbol *Sym = S.Sym;
22602293 StringRef Name = Sym->getName();
22612294 unsigned I = Sym->DynsymIndex;
......@@ -2270,7 +2303,8 @@ void HashTableSection::writeTo(uint8_t *Buf) {
22702303PltSection::PltSection(bool IsIplt)
22712304 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
22722305 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) {
22742308 // The PLT needs to be writable on SPARC as the dynamic linker will
22752309 // modify the instructions in the PLT entries.
22762310 if (Config->EMachine == EM_SPARCV9)
......@@ -2278,9 +2312,9 @@ PltSection::PltSection(bool IsIplt)
22782312}
22792313
22802314void PltSection::writeTo(uint8_t *Buf) {
2281 // At beginning of PLT but not the IPLT, we have code to call the dynamic
2315 // At beginning of PLT or retpoline IPLT, we have code to call the dynamic
22822316 // linker to resolve dynsyms at runtime. Write such code.
2283 if (!IsIplt)
2317 if (HeaderSize > 0)
22842318 Target->writePltHeader(Buf);
22852319 size_t Off = HeaderSize;
22862320 // The IPlt is immediately after the Plt, account for this in RelOff
......@@ -2298,9 +2332,9 @@ void PltSection::writeTo(uint8_t *Buf) {
22982332
22992333template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
23002334 Sym.PltIndex = Entries.size();
2301 RelocationBaseSection *PltRelocSection = InX::RelaPlt;
2335 RelocationBaseSection *PltRelocSection = In.RelaPlt;
23022336 if (IsIplt) {
2303 PltRelocSection = InX::RelaIplt;
2337 PltRelocSection = In.RelaIplt;
23042338 Sym.IsInIplt = true;
23052339 }
23062340 unsigned RelOff =
......@@ -2326,14 +2360,14 @@ void PltSection::addSymbols() {
23262360}
23272361
23282362unsigned PltSection::getPltRelocOff() const {
2329 return IsIplt ? InX::Plt->getSize() : 0;
2363 return IsIplt ? In.Plt->getSize() : 0;
23302364}
23312365
23322366// The string hash function for .gdb_index.
23332367static uint32_t computeGdbHash(StringRef S) {
23342368 uint32_t H = 0;
23352369 for (uint8_t C : S)
2336 H = H * 67 + tolower(C) - 113;
2370 H = H * 67 + toLower(C) - 113;
23372371 return H;
23382372}
23392373
......@@ -2371,7 +2405,7 @@ static std::vector<InputSection *> getDebugInfoSections() {
23712405
23722406static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
23732407 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())
23752409 Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
23762410 return Ret;
23772411}
......@@ -2381,12 +2415,15 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
23812415 std::vector<GdbIndexSection::AddressEntry> Ret;
23822416
23832417 uint32_t CuIdx = 0;
2384 for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) {
2385 DWARFAddressRangesVector Ranges;
2386 Cu->collectAddressRanges(Ranges);
2418 for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
2419 Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
2420 if (!Ranges) {
2421 error(toString(Sec) + ": " + toString(Ranges.takeError()));
2422 return {};
2423 }
23872424
23882425 ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
2389 for (DWARFAddressRange &R : Ranges) {
2426 for (DWARFAddressRange &R : *Ranges) {
23902427 InputSectionBase *S = Sections[R.SectionIndex];
23912428 if (!S || S == &InputSection::Discarded || !S->Live)
23922429 continue;
......@@ -2399,21 +2436,35 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
23992436 }
24002437 ++CuIdx;
24012438 }
2439
24022440 return Ret;
24032441}
24042442
2405static std::vector<GdbIndexSection::NameTypeEntry>
2406readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) {
2407 StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection();
2408 StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection();
2409
2410 std::vector<GdbIndexSection::NameTypeEntry> Ret;
2411 for (StringRef Sec : {Sec1, Sec2}) {
2412 DWARFDebugPubTable Table(Sec, Config->IsLE, true);
2413 for (const DWARFDebugPubTable::Set &Set : Table.getData())
2443template <class ELFT>
2444static std::vector<GdbIndexSection::NameAttrEntry>
2445readPubNamesAndTypes(const LLDDwarfObj<ELFT> &Obj,
2446 const std::vector<GdbIndexSection::CuEntry> &CUs) {
2447 const DWARFSection &PubNames = Obj.getGnuPubNamesSection();
2448 const DWARFSection &PubTypes = Obj.getGnuPubTypesSection();
2449
2450 std::vector<GdbIndexSection::NameAttrEntry> Ret;
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();
24142464 for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
24152465 Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
2416 (Ent.Descriptor.toBits() << 24) | Idx});
2466 (Ent.Descriptor.toBits() << 24) | I});
2467 }
24172468 }
24182469 return Ret;
24192470}
......@@ -2421,9 +2472,18 @@ readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) {
24212472// Create a list of symbols from a given list of symbol names and types
24222473// by uniquifying them by name.
24232474static 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) {
24252477 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
24282488 // The number of symbols we will handle in this function is of the order
24292489 // of millions for very large executables, so we use multi-threading to
......@@ -2441,21 +2501,24 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) {
24412501 // Instantiate GdbSymbols while uniqufying them by name.
24422502 std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
24432503 parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
2444 for (ArrayRef<NameTypeEntry> Entries : NameTypes) {
2445 for (const NameTypeEntry &Ent : Entries) {
2504 uint32_t I = 0;
2505 for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
2506 for (const NameAttrEntry &Ent : Entries) {
24462507 size_t ShardId = Ent.Name.hash() >> Shift;
24472508 if ((ShardId & (Concurrency - 1)) != ThreadId)
24482509 continue;
24492510
2511 uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
24502512 size_t &Idx = Map[ShardId][Ent.Name];
24512513 if (Idx) {
2452 Symbols[ShardId][Idx - 1].CuVector.push_back(Ent.Type);
2514 Symbols[ShardId][Idx - 1].CuVector.push_back(V);
24532515 continue;
24542516 }
24552517
24562518 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});
24582520 }
2521 ++I;
24592522 }
24602523 });
24612524
......@@ -2498,7 +2561,7 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
24982561 S->Live = false;
24992562
25002563 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
25032566 parallelForEachN(0, Sections.size(), [&](size_t I) {
25042567 ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
......@@ -2507,12 +2570,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
25072570 Chunks[I].Sec = Sections[I];
25082571 Chunks[I].CompilationUnits = readCuList(Dwarf);
25092572 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);
25112576 });
25122577
25132578 auto *Ret = make<GdbIndexSection>();
25142579 Ret->Chunks = std::move(Chunks);
2515 Ret->Symbols = createSymbols(NameTypes);
2580 Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
25162581 Ret->initOutputSize();
25172582 return Ret;
25182583}
......@@ -2570,8 +2635,9 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
25702635
25712636 // Write the string pool.
25722637 Hdr->ConstantPoolOff = Buf - Start;
2573 for (GdbSymbol &Sym : Symbols)
2638 parallelForEach(Symbols, [&](GdbSymbol &Sym) {
25742639 memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
2640 });
25752641
25762642 // Write the CU vectors.
25772643 for (GdbSymbol &Sym : Symbols) {
......@@ -2584,7 +2650,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
25842650 }
25852651}
25862652
2587bool GdbIndexSection::empty() const { return !Out::DebugInfo; }
2653bool GdbIndexSection::empty() const { return Chunks.empty(); }
25882654
25892655EhFrameHeader::EhFrameHeader()
25902656 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
......@@ -2596,13 +2662,13 @@ EhFrameHeader::EhFrameHeader()
25962662void EhFrameHeader::writeTo(uint8_t *Buf) {
25972663 typedef EhFrameSection::FdeData FdeData;
25982664
2599 std::vector<FdeData> Fdes = InX::EhFrame->getFdeData();
2665 std::vector<FdeData> Fdes = In.EhFrame->getFdeData();
26002666
26012667 Buf[0] = 1;
26022668 Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
26032669 Buf[2] = DW_EH_PE_udata4;
26042670 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);
26062672 write32(Buf + 8, Fdes.size());
26072673 Buf += 12;
26082674
......@@ -2615,13 +2681,12 @@ void EhFrameHeader::writeTo(uint8_t *Buf) {
26152681
26162682size_t EhFrameHeader::getSize() const {
26172683 // .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;
26192685}
26202686
2621bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); }
2687bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }
26222688
2623template <class ELFT>
2624VersionDefinitionSection<ELFT>::VersionDefinitionSection()
2689VersionDefinitionSection::VersionDefinitionSection()
26252690 : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
26262691 ".gnu.version_d") {}
26272692
......@@ -2631,12 +2696,13 @@ static StringRef getFileDefName() {
26312696 return Config->OutputFile;
26322697}
26332698
2634template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
2635 FileDefNameOff = InX::DynStrTab->addString(getFileDefName());
2699void VersionDefinitionSection::finalizeContents() {
2700 FileDefNameOff = In.DynStrTab->addString(getFileDefName());
26362701 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
26412707 // sh_info should be set to the number of definitions. This fact is missed in
26422708 // documentation, but confirmed by binutils community:
......@@ -2644,68 +2710,68 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
26442710 getParent()->Info = getVerDefNum();
26452711}
26462712
2647template <class ELFT>
2648void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index,
2649 StringRef Name, size_t NameOff) {
2650 auto *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
2651 Verdef->vd_version = 1;
2652 Verdef->vd_cnt = 1;
2653 Verdef->vd_aux = sizeof(Elf_Verdef);
2654 Verdef->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
2655 Verdef->vd_flags = (Index == 1 ? VER_FLG_BASE : 0);
2656 Verdef->vd_ndx = Index;
2657 Verdef->vd_hash = hashSysV(Name);
2658
2659 auto *Verdaux = reinterpret_cast<Elf_Verdaux *>(Buf + sizeof(Elf_Verdef));
2660 Verdaux->vda_name = NameOff;
2661 Verdaux->vda_next = 0;
2713void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
2714 StringRef Name, size_t NameOff) {
2715 uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
2716
2717 // Write a verdef.
2718 write16(Buf, 1); // vd_version
2719 write16(Buf + 2, Flags); // vd_flags
2720 write16(Buf + 4, Index); // vd_ndx
2721 write16(Buf + 6, 1); // vd_cnt
2722 write32(Buf + 8, hashSysV(Name)); // vd_hash
2723 write32(Buf + 12, 20); // vd_aux
2724 write32(Buf + 16, 28); // vd_next
2725
2726 // Write a veraux.
2727 write32(Buf + 20, NameOff); // vda_name
2728 write32(Buf + 24, 0); // vda_next
26622729}
26632730
2664template <class ELFT>
2665void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
2731void VersionDefinitionSection::writeTo(uint8_t *Buf) {
26662732 writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
26672733
26682734 for (VersionDefinition &V : Config->VersionDefinitions) {
2669 Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
2735 Buf += EntrySize;
26702736 writeOne(Buf, V.Id, V.Name, V.NameOff);
26712737 }
26722738
26732739 // Need to terminate the last version definition.
2674 Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
2675 Verdef->vd_next = 0;
2740 write32(Buf + 16, 0); // vd_next
26762741}
26772742
2678template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const {
2679 return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();
2743size_t VersionDefinitionSection::getSize() const {
2744 return EntrySize * getVerDefNum();
26802745}
26812746
2747// .gnu.version is a table where each entry is 2 byte long.
26822748template <class ELFT>
26832749VersionTableSection<ELFT>::VersionTableSection()
26842750 : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
26852751 ".gnu.version") {
2686 this->Entsize = sizeof(Elf_Versym);
2752 this->Entsize = 2;
26872753}
26882754
26892755template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
26902756 // At the moment of june 2016 GNU docs does not mention that sh_link field
26912757 // 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;
26932759}
26942760
26952761template <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;
26972763}
26982764
26992765template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
2700 auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;
2701 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
2702 OutVersym->vs_index = S.Sym->VersionId;
2703 ++OutVersym;
2766 Buf += 2;
2767 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
2768 write16(Buf, S.Sym->VersionId);
2769 Buf += 2;
27042770 }
27052771}
27062772
27072773template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
2708 return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();
2774 return !In.VerDef && InX<ELFT>::VerNeed->empty();
27092775}
27102776
27112777template <class ELFT>
......@@ -2729,7 +2795,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
27292795 // to create one by adding it to our needed list and creating a dynstr entry
27302796 // for the soname.
27312797 if (File.VerdefMap.empty())
2732 Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)});
2798 Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
27332799 const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
27342800 typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
27352801
......@@ -2737,8 +2803,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
27372803 // prepare to create one by allocating a version identifier and creating a
27382804 // dynstr entry for the version name.
27392805 if (NV.Index == 0) {
2740 NV.StrTab = InX::DynStrTab->addString(File.getStringTable().data() +
2741 Ver->getAux()->vda_name);
2806 NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() +
2807 Ver->getAux()->vda_name);
27422808 NV.Index = NextIndex++;
27432809 }
27442810 SS->VersionId = NV.Index;
......@@ -2780,7 +2846,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
27802846}
27812847
27822848template <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;
27842851 getParent()->Info = Needed.size();
27852852}
27862853
......@@ -2896,12 +2963,6 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
28962963 return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
28972964}
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
29052966template <class ELFT> void elf::splitSections() {
29062967 // splitIntoPieces needs to be called on each MergeInputSection
29072968 // before calling finalizeContents().
......@@ -3040,34 +3101,54 @@ bool ThunkSection::assignOffsets() {
30403101 return Changed;
30413102}
30423103
3043InputSection *InX::ARMAttributes;
3044BssSection *InX::Bss;
3045BssSection *InX::BssRelRo;
3046BuildIdSection *InX::BuildId;
3047EhFrameHeader *InX::EhFrameHdr;
3048EhFrameSection *InX::EhFrame;
3049SyntheticSection *InX::Dynamic;
3050StringTableSection *InX::DynStrTab;
3051SymbolTableBaseSection *InX::DynSymTab;
3052InputSection *InX::Interp;
3053GdbIndexSection *InX::GdbIndex;
3054GotSection *InX::Got;
3055GotPltSection *InX::GotPlt;
3056GnuHashTableSection *InX::GnuHashTab;
3057HashTableSection *InX::HashTab;
3058IgotPltSection *InX::IgotPlt;
3059MipsGotSection *InX::MipsGot;
3060MipsRldMapSection *InX::MipsRldMap;
3061PltSection *InX::Plt;
3062PltSection *InX::Iplt;
3063RelocationBaseSection *InX::RelaDyn;
3064RelrBaseSection *InX::RelrDyn;
3065RelocationBaseSection *InX::RelaPlt;
3066RelocationBaseSection *InX::RelaIplt;
3067StringTableSection *InX::ShStrTab;
3068StringTableSection *InX::StrTab;
3069SymbolTableBaseSection *InX::SymTab;
3070SymtabShndxSection *InX::SymTabShndx;
3104// If linking position-dependent code then the table will store the addresses
3105// directly in the binary so the section has type SHT_PROGBITS. If linking
3106// position-independent code the section has type SHT_NOBITS since it will be
3107// allocated and filled in by the dynamic linker.
3108PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
3109 : SyntheticSection(SHF_ALLOC | SHF_WRITE,
3110 Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
3111 ".branch_lt") {}
3112
3113void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
3114 assert(Sym.PPC64BranchltIndex == 0xffff);
3115 Sym.PPC64BranchltIndex = Entries.size();
3116 Entries.push_back(&Sym);
3117}
3118
3119size_t PPC64LongBranchTargetSection::getSize() const {
3120 return Entries.size() * 8;
3121}
3122
3123void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
3124 assert(Target->GotPltEntrySize == 8);
3125 // If linking non-pic we have the final addresses of the targets and they get
3126 // written to the table directly. For pic the dynamic linker will allocate
3127 // the section and fill it it.
3128 if (Config->Pic)
3129 return;
3130
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
30723153template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
30733154template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
......@@ -3143,8 +3224,3 @@ template class elf::VersionNeedSection<ELF32LE>;
31433224template class elf::VersionNeedSection<ELF32BE>;
31443225template class elf::VersionNeedSection<ELF64LE>;
31453226template 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 @@
2121#ifndef LLD_ELF_SYNTHETIC_SECTION_H
2222#define LLD_ELF_SYNTHETIC_SECTION_H
2323
24#include "DWARF.h"
2425#include "EhFrame.h"
25#include "GdbIndex.h"
2626#include "InputSection.h"
2727#include "llvm/ADT/MapVector.h"
2828#include "llvm/MC/StringTableBuilder.h"
......@@ -50,8 +50,6 @@ public:
5050 // If the section has the SHF_ALLOC flag and the size may be changed if
5151 // thunks are added, update the section size.
5252 virtual bool updateAllocSize() { return false; }
53 // If any additional finalization of contents are needed post thunk creation.
54 virtual void postThunkContents() {}
5553 virtual bool empty() const { return false; }
5654
5755 static bool classof(const SectionBase *D) {
......@@ -137,6 +135,15 @@ protected:
137135 uint64_t Size = 0;
138136};
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
140147// .note.gnu.build-id section.
141148class BuildIdSection : public SyntheticSection {
142149 // First 16 bytes are a header.
......@@ -163,7 +170,9 @@ private:
163170class BssSection final : public SyntheticSection {
164171public:
165172 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 }
167176 bool empty() const override { return getSize() == 0; }
168177 size_t getSize() const override { return Size; }
169178
......@@ -300,8 +309,6 @@ private:
300309
301310 uint64_t Size = 0;
302311
303 size_t LocalEntriesNum = 0;
304
305312 // Symbol and addend.
306313 typedef std::pair<Symbol *, int64_t> GotEntry;
307314
......@@ -333,8 +340,6 @@ private:
333340 size_t getPageEntriesNum() const;
334341 // Number of entries require 16-bit index to access.
335342 size_t getIndexedEntriesNum() const;
336
337 bool isOverflow() const;
338343 };
339344
340345 // Container of GOT created for each input file.
......@@ -529,6 +534,7 @@ struct RelativeReloc {
529534class RelrBaseSection : public SyntheticSection {
530535public:
531536 RelrBaseSection();
537 bool empty() const override { return Relocs.empty(); }
532538 std::vector<RelativeReloc> Relocs;
533539};
534540
......@@ -561,7 +567,6 @@ class SymbolTableBaseSection : public SyntheticSection {
561567public:
562568 SymbolTableBaseSection(StringTableSection &StrTabSec);
563569 void finalizeContents() override;
564 void postThunkContents() override;
565570 size_t getSize() const override { return getNumSymbols() * Entsize; }
566571 void addSymbol(Symbol *Sym);
567572 unsigned getNumSymbols() const { return Symbols.size() + 1; }
......@@ -569,6 +574,8 @@ public:
569574 ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
570575
571576protected:
577 void sortSymTabSymbols();
578
572579 // A vector of symbols and their string table offsets.
573580 std::vector<SymbolTableEntry> Symbols;
574581
......@@ -612,7 +619,8 @@ public:
612619 void addSymbols(std::vector<SymbolTableEntry> &Symbols);
613620
614621private:
615 enum { Shift2 = 6 };
622 // See the comment in writeBloomFilter.
623 enum { Shift2 = 26 };
616624
617625 void writeBloomFilter(uint8_t *Buf);
618626 void writeHashTable(uint8_t *Buf);
......@@ -652,13 +660,13 @@ public:
652660 size_t getSize() const override;
653661 bool empty() const override { return Entries.empty(); }
654662 void addSymbols();
655
656663 template <class ELFT> void addEntry(Symbol &Sym);
657664
665 size_t HeaderSize;
666
658667private:
659668 unsigned getPltRelocOff() const;
660669 std::vector<std::pair<const Symbol *, unsigned>> Entries;
661 size_t HeaderSize;
662670 bool IsIplt;
663671};
664672
......@@ -676,9 +684,9 @@ public:
676684 uint64_t CuLength;
677685 };
678686
679 struct NameTypeEntry {
687 struct NameAttrEntry {
680688 llvm::CachedHashStringRef Name;
681 uint32_t Type;
689 uint32_t CuIndexAndAttrs;
682690 };
683691
684692 struct GdbChunk {
......@@ -748,11 +756,7 @@ public:
748756// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
749757// The section shall contain an array of Elf_Verdef structures, optionally
750758// followed by an array of Elf_Verdaux structures.
751template <class ELFT>
752759class VersionDefinitionSection final : public SyntheticSection {
753 typedef typename ELFT::Verdef Elf_Verdef;
754 typedef typename ELFT::Verdaux Elf_Verdaux;
755
756760public:
757761 VersionDefinitionSection();
758762 void finalizeContents() override;
......@@ -760,6 +764,7 @@ public:
760764 void writeTo(uint8_t *Buf) override;
761765
762766private:
767 enum { EntrySize = 28 };
763768 void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
764769
765770 unsigned FileDefNameOff;
......@@ -773,8 +778,6 @@ private:
773778// the own object or in any of the dependencies.
774779template <class ELFT>
775780class VersionTableSection final : public SyntheticSection {
776 typedef typename ELFT::Versym Elf_Versym;
777
778781public:
779782 VersionTableSection();
780783 void finalizeContents() override;
......@@ -964,9 +967,27 @@ private:
964967 size_t Size = 0;
965968};
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
967989InputSection *createInterpSection();
968990MergeInputSection *createCommentSection();
969void decompressSections();
970991template <class ELFT> void splitSections();
971992void mergeSections();
972993
......@@ -974,46 +995,48 @@ Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
974995 uint64_t Size, InputSectionBase &Section);
975996
976997// Linker generated sections which can be used as inputs.
977struct InX {
978 static InputSection *ARMAttributes;
979 static BssSection *Bss;
980 static BssSection *BssRelRo;
981 static BuildIdSection *BuildId;
982 static EhFrameHeader *EhFrameHdr;
983 static EhFrameSection *EhFrame;
984 static SyntheticSection *Dynamic;
985 static StringTableSection *DynStrTab;
986 static SymbolTableBaseSection *DynSymTab;
987 static GnuHashTableSection *GnuHashTab;
988 static HashTableSection *HashTab;
989 static InputSection *Interp;
990 static GdbIndexSection *GdbIndex;
991 static GotSection *Got;
992 static GotPltSection *GotPlt;
993 static IgotPltSection *IgotPlt;
994 static MipsGotSection *MipsGot;
995 static MipsRldMapSection *MipsRldMap;
996 static PltSection *Plt;
997 static PltSection *Iplt;
998 static RelocationBaseSection *RelaDyn;
999 static RelrBaseSection *RelrDyn;
1000 static RelocationBaseSection *RelaPlt;
1001 static RelocationBaseSection *RelaIplt;
1002 static StringTableSection *ShStrTab;
1003 static StringTableSection *StrTab;
1004 static SymbolTableBaseSection *SymTab;
1005 static SymtabShndxSection* SymTabShndx;
1006};
1007
1008template <class ELFT> struct In {
1009 static VersionDefinitionSection<ELFT> *VerDef;
998struct InStruct {
999 InputSection *ARMAttributes;
1000 BssSection *Bss;
1001 BssSection *BssRelRo;
1002 BuildIdSection *BuildId;
1003 EhFrameHeader *EhFrameHdr;
1004 EhFrameSection *EhFrame;
1005 SyntheticSection *Dynamic;
1006 StringTableSection *DynStrTab;
1007 SymbolTableBaseSection *DynSymTab;
1008 GnuHashTableSection *GnuHashTab;
1009 HashTableSection *HashTab;
1010 InputSection *Interp;
1011 GdbIndexSection *GdbIndex;
1012 GotSection *Got;
1013 GotPltSection *GotPlt;
1014 IgotPltSection *IgotPlt;
1015 PPC64LongBranchTargetSection *PPC64LongBranchTarget;
1016 MipsGotSection *MipsGot;
1017 MipsRldMapSection *MipsRldMap;
1018 PltSection *Plt;
1019 PltSection *Iplt;
1020 RelocationBaseSection *RelaDyn;
1021 RelrBaseSection *RelrDyn;
1022 RelocationBaseSection *RelaPlt;
1023 RelocationBaseSection *RelaIplt;
1024 StringTableSection *ShStrTab;
1025 StringTableSection *StrTab;
1026 SymbolTableBaseSection *SymTab;
1027 SymtabShndxSection *SymTabShndx;
1028 VersionDefinitionSection *VerDef;
1029};
1030
1031extern InStruct In;
1032
1033template <class ELFT> struct InX {
10101034 static VersionTableSection<ELFT> *VerSym;
10111035 static VersionNeedSection<ELFT> *VerNeed;
10121036};
10131037
1014template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
1015template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
1016template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
1038template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
1039template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
10171040} // namespace elf
10181041} // namespace lld
10191042
deps/lld/ELF/Target.cpp+8-5
......@@ -73,12 +73,16 @@ TargetInfo *elf::getTarget() {
7373 case ELF64BEKind:
7474 return getMipsTargetInfo<ELF64BE>();
7575 default:
76 fatal("unsupported MIPS target");
76 llvm_unreachable("unsupported MIPS target");
7777 }
78 case EM_MSP430:
79 return getMSP430TargetInfo();
7880 case EM_PPC:
7981 return getPPCTargetInfo();
8082 case EM_PPC64:
8183 return getPPC64TargetInfo();
84 case EM_RISCV:
85 return getRISCVTargetInfo();
8286 case EM_SPARCV9:
8387 return getSPARCV9TargetInfo();
8488 case EM_X86_64:
......@@ -86,7 +90,7 @@ TargetInfo *elf::getTarget() {
8690 return getX32TargetInfo();
8791 return getX86_64TargetInfo();
8892 }
89 fatal("unknown target machine");
93 llvm_unreachable("unknown target machine");
9094}
9195
9296template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {
......@@ -130,12 +134,11 @@ bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
130134 return false;
131135}
132136
133bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc,
134 uint8_t *End) const {
137bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
138 uint8_t StOther) const {
135139 llvm_unreachable("Target doesn't support split stacks.");
136140}
137141
138
139142bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
140143 return true;
141144}
deps/lld/ELF/Target.h+36-28
......@@ -13,6 +13,8 @@
1313#include "InputSection.h"
1414#include "lld/Common/ErrorHandler.h"
1515#include "llvm/Object/ELF.h"
16#include "llvm/Support/MathExtras.h"
17#include <array>
1618
1719namespace lld {
1820std::string toString(elf::RelType Type);
......@@ -43,10 +45,6 @@ public:
4345 virtual void addPltHeaderSymbols(InputSection &IS) const {}
4446 virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}
4547
46 unsigned getPltEntryOffset(unsigned Index) const {
47 return Index * PltEntrySize + PltHeaderSize;
48 }
49
5048 // Returns true if a relocation only uses the low bits of a value such that
5149 // all those bits are in the same page. For example, if the relocation
5250 // only uses the low 12 bits in a system with 4k pages. If this is true, the
......@@ -60,11 +58,18 @@ public:
6058 const InputFile *File, uint64_t BranchAddr,
6159 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
6366 // The function with a prologue starting at Loc was compiled with
6467 // -fsplit-stack and it calls a function compiled without. Adjust the prologue
6568 // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
66 virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc,
67 uint8_t *End) const;
69 // The symbols st_other flags are needed on PowerPC64 for determining the
70 // offset to the split-stack prologue.
71 virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
72 uint8_t StOther) const;
6873
6974 // Return true if we can reach Dst from Src with Relocation RelocType
7075 virtual bool inBranchRange(RelType Type, uint64_t Src,
......@@ -87,12 +92,9 @@ public:
8792 // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
8893 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
9495 RelType CopyRel;
9596 RelType GotRel;
97 RelType NoneRel;
9698 RelType PltRel;
9799 RelType RelativeRel;
98100 RelType IRelativeRel;
......@@ -112,20 +114,16 @@ public:
112114 // On PPC ELF V2 abi, the first entry in the .got is the .TOC.
113115 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
124117 bool NeedsThunks = false;
125118
126119 // A 4-byte field corresponding to one or more trap instructions, used to pad
127120 // 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
130128 virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
131129 RelExpr Expr) const;
......@@ -148,8 +146,10 @@ TargetInfo *getAMDGPUTargetInfo();
148146TargetInfo *getARMTargetInfo();
149147TargetInfo *getAVRTargetInfo();
150148TargetInfo *getHexagonTargetInfo();
149TargetInfo *getMSP430TargetInfo();
151150TargetInfo *getPPC64TargetInfo();
152151TargetInfo *getPPCTargetInfo();
152TargetInfo *getRISCVTargetInfo();
153153TargetInfo *getSPARCV9TargetInfo();
154154TargetInfo *getX32TargetInfo();
155155TargetInfo *getX86TargetInfo();
......@@ -168,6 +168,15 @@ static inline std::string getErrorLocation(const uint8_t *Loc) {
168168 return getErrorPlace(Loc).Loc;
169169}
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
171180uint64_t getPPC64TocBase();
172181uint64_t getAArch64Page(uint64_t Expr);
173182
......@@ -184,19 +193,18 @@ static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,
184193 Hint = "; consider recompiling with -fdebug-types-section to reduce size "
185194 "of debug sections";
186195
187 error(ErrPlace.Loc + "relocation " + lld::toString(Type) +
188 " out of range: " + V.str() + " is not in [" + Twine(Min).str() + ", " +
189 Twine(Max).str() + "]" + Hint);
196 errorOrWarn(ErrPlace.Loc + "relocation " + lld::toString(Type) +
197 " out of range: " + V.str() + " is not in [" + Twine(Min).str() +
198 ", " + Twine(Max).str() + "]" + Hint);
190199}
191200
192// Sign-extend Nth bit all the way to MSB.
193inline int64_t signExtend(uint64_t V, int N) {
194 return int64_t(V << (64 - N)) >> (64 - N);
201inline unsigned getPltEntryOffset(unsigned Idx) {
202 return Target->PltHeaderSize + Target->PltEntrySize * Idx;
195203}
196204
197205// Make sure that V can be represented as an N bit signed integer.
198206inline 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))
200208 reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));
201209}
202210
......@@ -210,7 +218,7 @@ inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
210218inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
211219 // For the error message we should cast V to a signed integer so that error
212220 // 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)
214222 reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
215223 llvm::maxIntN(N));
216224}
deps/lld/ELF/Thunks.cpp+280-24
......@@ -159,6 +159,50 @@ public:
159159 void addSymbols(ThunkSection &IS) override;
160160};
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
162206// MIPS LA25 thunk
163207class MipsThunk final : public Thunk {
164208public:
......@@ -209,6 +253,46 @@ public:
209253 void addSymbols(ThunkSection &IS) override;
210254};
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
212296} // end anonymous namespace
213297
214298Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
......@@ -395,12 +479,12 @@ void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
395479 const uint8_t Data[] = {
396480 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)
397481 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)
398 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
399 0x1c, 0xff, 0x2f, 0xe1, // bx r12
482 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
483 0x1c, 0xff, 0x2f, 0xe1, // bx ip
400484 };
401485 uint64_t S = getARMThunkDestVA(Destination);
402486 uint64_t P = getThunkTargetSym()->getVA();
403 uint64_t Offset = S - P - 16;
487 int64_t Offset = S - P - 16;
404488 memcpy(Buf, Data, sizeof(Data));
405489 Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
406490 Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
......@@ -416,12 +500,12 @@ void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
416500 const uint8_t Data[] = {
417501 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
418502 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
419 0xfc, 0x44, // L1: add r12, pc
420 0x60, 0x47, // bx r12
503 0xfc, 0x44, // L1: add ip, pc
504 0x60, 0x47, // bx ip
421505 };
422506 uint64_t S = getARMThunkDestVA(Destination);
423507 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
424 uint64_t Offset = S - P - 12;
508 int64_t Offset = S - P - 12;
425509 memcpy(Buf, Data, sizeof(Data));
426510 Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
427511 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
......@@ -433,6 +517,102 @@ void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
433517 addSymbol("$t", STT_NOTYPE, 0, IS);
434518}
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
436616// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
437617void MipsThunk::writeTo(uint8_t *Buf) {
438618 uint64_t S = Destination.getVA();
......@@ -502,17 +682,21 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
502682 return dyn_cast<InputSection>(DR.Section);
503683}
504684
505void PPC64PltCallStub::writeTo(uint8_t *Buf) {
506 int64_t Off = Destination.getGotPltVA() - getPPC64TocBase();
507 // Need to add 0x8000 to offset to account for the low bits being signed.
508 uint16_t OffHa = (Off + 0x8000) >> 16;
509 uint16_t OffLo = Off;
685static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
686 uint16_t OffHa = (Offset + 0x8000) >> 16;
687 uint16_t OffLo = Offset & 0xffff;
510688
511 write32(Buf + 0, 0xf8410018); // std r2,24(r1)
512 write32(Buf + 4, 0x3d820000 | OffHa); // addis r12,r2, X@plt@to@ha
513 write32(Buf + 8, 0xe98c0000 | OffLo); // ld r12,X@plt@toc@l(r12)
514 write32(Buf + 12, 0x7d8903a6); // mtctr r12
515 write32(Buf + 16, 0x4e800420); // bctr
689 write32(Buf + 0, 0x3d820000 | OffHa); // addis r12, r2, OffHa
690 write32(Buf + 4, 0xe98c0000 | OffLo); // ld r12, OffLo(r12)
691 write32(Buf + 8, 0x7d8903a6); // mtctr r12
692 write32(Buf + 12, 0x4e800420); // bctr
693}
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);
516700}
517701
518702void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
......@@ -521,6 +705,16 @@ void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
521705 S->NeedsTocRestore = true;
522706}
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
524718Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
525719
526720Thunk::~Thunk() = default;
......@@ -528,28 +722,85 @@ Thunk::~Thunk() = default;
528722static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
529723 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
530724 fatal("unrecognized relocation type");
531 if (Config->Pic)
725 if (Config->PicThunk)
532726 return make<AArch64ADRPThunk>(S);
533727 return make<AArch64ABSLongThunk>(S);
534728}
535729
536730// Creates a thunk for Thumb-ARM interworking.
537static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
538 // ARM relocations need ARM to Thumb interworking Thunks.
539 // Thumb relocations need Thumb to ARM relocations.
540 // Use position independent Thunks if we require position independent code.
731// Arm Architectures v5 and v6 do not support Thumb2 technology. This means
732// - MOVT and MOVW instructions cannot be used
733// - Only Thumb relocation that can generate a Thunk is a BL, this can always
734// be transformed into a BLX
735static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
541736 switch (Reloc) {
542737 case R_ARM_PC24:
543738 case R_ARM_PLT32:
544739 case R_ARM_JUMP24:
545740 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:
546760 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)
547798 return make<ARMV7PILongThunk>(S);
548799 return make<ARMV7ABSLongThunk>(S);
549800 case R_ARM_THM_JUMP19:
550801 case R_ARM_THM_JUMP24:
551802 case R_ARM_THM_CALL:
552 if (Config->Pic)
803 if (Config->PicThunk)
553804 return make<ThumbV7PILongThunk>(S);
554805 return make<ThumbV7ABSLongThunk>(S);
555806 }
......@@ -565,9 +816,14 @@ static Thunk *addThunkMips(RelType Type, Symbol &S) {
565816}
566817
567818static 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())
569821 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);
571827}
572828
573829Thunk *addThunk(RelType Type, Symbol &S) {
deps/lld/ELF/Writer.cpp+403-282
......@@ -53,8 +53,10 @@ private:
5353 void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
5454 void sortSections();
5555 void resolveShfLinkOrder();
56 void maybeAddThunks();
5657 void sortInputSections();
5758 void finalizeSections();
59 void checkExecuteOnly();
5860 void setReservedSymbolSections();
5961
6062 std::vector<PhdrEntry *> createPhdrs();
......@@ -77,7 +79,6 @@ private:
7779 void addRelIpltSymbols();
7880 void addStartEndSymbols();
7981 void addStartStopSymbols(OutputSection *Sec);
80 uint64_t getEntryAddr();
8182
8283 std::vector<PhdrEntry *> Phdrs;
8384
......@@ -114,18 +115,16 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {
114115 // for instance.
115116 if (Config->ZKeepTextSectionPrefix)
116117 for (StringRef V :
117 {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) {
118 {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})
118119 if (isSectionPrefix(V, S->Name))
119120 return V.drop_back();
120 }
121121
122122 for (StringRef V :
123123 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
124124 ".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."})
126126 if (isSectionPrefix(V, S->Name))
127127 return V.drop_back();
128 }
129128
130129 // CommonSection is identified as "COMMON" in linker scripts.
131130 // By default, it should go to .bss section.
......@@ -159,7 +158,7 @@ template <class ELFT> static void combineEhFrameSections() {
159158 if (!ES || !ES->Live)
160159 continue;
161160
162 InX::EhFrame->addSection<ELFT>(ES);
161 In.EhFrame->addSection<ELFT>(ES);
163162 S = nullptr;
164163 }
165164
......@@ -173,10 +172,14 @@ static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
173172 Symbol *S = Symtab->find(Name);
174173 if (!S || S->isDefined())
175174 return nullptr;
176 Symbol *Sym = Symtab->addRegular(Name, StOther, STT_NOTYPE, Val,
177 /*Size=*/0, Binding, Sec,
178 /*File=*/nullptr);
179 return cast<Defined>(Sym);
175 return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val,
176 /*Size=*/0, Binding, Sec,
177 /*File=*/nullptr);
178}
179
180static Defined *addAbsolute(StringRef Name) {
181 return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL,
182 nullptr, nullptr);
180183}
181184
182185// The linker is expected to define some symbols depending on
......@@ -188,21 +191,19 @@ void elf::addReservedSymbols() {
188191 // to GOT. Default offset is 0x7ff0.
189192 // See "Global Data Symbols" in Chapter 6 in the following document:
190193 // 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
193196 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
194197 // start of function and 'gp' pointer into GOT.
195198 if (Symtab->find("_gp_disp"))
196 ElfSym::MipsGpDisp =
197 Symtab->addAbsolute("_gp_disp", STV_HIDDEN, STB_GLOBAL);
199 ElfSym::MipsGpDisp = addAbsolute("_gp_disp");
198200
199201 // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
200202 // pointer. This symbol is used in the code generated by .cpload pseudo-op
201203 // in case of using -mno-shared option.
202204 // https://sourceware.org/ml/binutils/2004-12/msg00094.html
203205 if (Symtab->find("__gnu_local_gp"))
204 ElfSym::MipsLocalGp =
205 Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
206 ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");
206207 }
207208
208209 // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which
......@@ -211,9 +212,20 @@ void elf::addReservedSymbols() {
211212 // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to
212213 // represent the TOC base which is offset by 0x8000 bytes from the start of
213214 // the .got section.
214 ElfSym::GlobalOffsetTable = addOptionalRegular(
215 (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_",
216 Out::ElfHeader, Target->GotBaseSymOff);
215 // We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the
216 // correctness of some relocations depends on its value.
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
218230 // __ehdr_start is the location of ELF file headers. Note that we define
219231 // this symbol unconditionally even when using a linker script, which
......@@ -263,54 +275,52 @@ template <class ELFT> static void createSyntheticSections() {
263275
264276 auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
265277
266 InX::DynStrTab = make<StringTableSection>(".dynstr", true);
267 InX::Dynamic = make<DynamicSection<ELFT>>();
278 In.DynStrTab = make<StringTableSection>(".dynstr", true);
279 In.Dynamic = make<DynamicSection<ELFT>>();
268280 if (Config->AndroidPackDynRelocs) {
269 InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
281 In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
270282 Config->IsRela ? ".rela.dyn" : ".rel.dyn");
271283 } else {
272 InX::RelaDyn = make<RelocationSection<ELFT>>(
284 In.RelaDyn = make<RelocationSection<ELFT>>(
273285 Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
274286 }
275 InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
287 In.ShStrTab = make<StringTableSection>(".shstrtab", false);
276288
277289 Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
278290 Out::ProgramHeaders->Alignment = Config->Wordsize;
279291
280292 if (needsInterpSection()) {
281 InX::Interp = createInterpSection();
282 Add(InX::Interp);
283 } else {
284 InX::Interp = nullptr;
293 In.Interp = createInterpSection();
294 Add(In.Interp);
285295 }
286296
287297 if (Config->Strip != StripPolicy::All) {
288 InX::StrTab = make<StringTableSection>(".strtab", false);
289 InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
290 InX::SymTabShndx = make<SymtabShndxSection>();
298 In.StrTab = make<StringTableSection>(".strtab", false);
299 In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
300 In.SymTabShndx = make<SymtabShndxSection>();
291301 }
292302
293303 if (Config->BuildId != BuildIdKind::None) {
294 InX::BuildId = make<BuildIdSection>();
295 Add(InX::BuildId);
304 In.BuildId = make<BuildIdSection>();
305 Add(In.BuildId);
296306 }
297307
298 InX::Bss = make<BssSection>(".bss", 0, 1);
299 Add(InX::Bss);
308 In.Bss = make<BssSection>(".bss", 0, 1);
309 Add(In.Bss);
300310
301311 // If there is a SECTIONS command and a .data.rel.ro section name use name
302312 // .data.rel.ro.bss so that we match in the .data.rel.ro output section.
303313 // This makes sure our relro is contiguous.
304314 bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");
305 InX::BssRelRo =
315 In.BssRelRo =
306316 make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
307 Add(InX::BssRelRo);
317 Add(In.BssRelRo);
308318
309319 // Add MIPS-specific sections.
310320 if (Config->EMachine == EM_MIPS) {
311321 if (!Config->Shared && Config->HasDynSymTab) {
312 InX::MipsRldMap = make<MipsRldMapSection>();
313 Add(InX::MipsRldMap);
322 In.MipsRldMap = make<MipsRldMapSection>();
323 Add(In.MipsRldMap);
314324 }
315325 if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
316326 Add(Sec);
......@@ -321,65 +331,70 @@ template <class ELFT> static void createSyntheticSections() {
321331 }
322332
323333 if (Config->HasDynSymTab) {
324 InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
325 Add(InX::DynSymTab);
334 In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
335 Add(In.DynSymTab);
326336
327 In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
328 Add(In<ELFT>::VerSym);
337 InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
338 Add(InX<ELFT>::VerSym);
329339
330340 if (!Config->VersionDefinitions.empty()) {
331 In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
332 Add(In<ELFT>::VerDef);
341 In.VerDef = make<VersionDefinitionSection>();
342 Add(In.VerDef);
333343 }
334344
335 In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
336 Add(In<ELFT>::VerNeed);
345 InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
346 Add(InX<ELFT>::VerNeed);
337347
338348 if (Config->GnuHash) {
339 InX::GnuHashTab = make<GnuHashTableSection>();
340 Add(InX::GnuHashTab);
349 In.GnuHashTab = make<GnuHashTableSection>();
350 Add(In.GnuHashTab);
341351 }
342352
343353 if (Config->SysvHash) {
344 InX::HashTab = make<HashTableSection>();
345 Add(InX::HashTab);
354 In.HashTab = make<HashTableSection>();
355 Add(In.HashTab);
346356 }
347357
348 Add(InX::Dynamic);
349 Add(InX::DynStrTab);
350 Add(InX::RelaDyn);
358 Add(In.Dynamic);
359 Add(In.DynStrTab);
360 Add(In.RelaDyn);
351361 }
352362
353363 if (Config->RelrPackDynRelocs) {
354 InX::RelrDyn = make<RelrSection<ELFT>>();
355 Add(InX::RelrDyn);
364 In.RelrDyn = make<RelrSection<ELFT>>();
365 Add(In.RelrDyn);
356366 }
357367
358368 // Add .got. MIPS' .got is so different from the other archs,
359369 // it has its own class.
360370 if (Config->EMachine == EM_MIPS) {
361 InX::MipsGot = make<MipsGotSection>();
362 Add(InX::MipsGot);
371 In.MipsGot = make<MipsGotSection>();
372 Add(In.MipsGot);
363373 } else {
364 InX::Got = make<GotSection>();
365 Add(InX::Got);
374 In.Got = make<GotSection>();
375 Add(In.Got);
366376 }
367377
368 InX::GotPlt = make<GotPltSection>();
369 Add(InX::GotPlt);
370 InX::IgotPlt = make<IgotPltSection>();
371 Add(InX::IgotPlt);
378 if (Config->EMachine == EM_PPC64) {
379 In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>();
380 Add(In.PPC64LongBranchTarget);
381 }
382
383 In.GotPlt = make<GotPltSection>();
384 Add(In.GotPlt);
385 In.IgotPlt = make<IgotPltSection>();
386 Add(In.IgotPlt);
372387
373388 if (Config->GdbIndex) {
374 InX::GdbIndex = GdbIndexSection::create<ELFT>();
375 Add(InX::GdbIndex);
389 In.GdbIndex = GdbIndexSection::create<ELFT>();
390 Add(In.GdbIndex);
376391 }
377392
378393 // We always need to add rel[a].plt to output if it has entries.
379394 // Even for static linking it can contain R_[*]_IRELATIVE relocations.
380 InX::RelaPlt = make<RelocationSection<ELFT>>(
395 In.RelaPlt = make<RelocationSection<ELFT>>(
381396 Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
382 Add(InX::RelaPlt);
397 Add(In.RelaPlt);
383398
384399 // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
385400 // that the IRelative relocations are processed last by the dynamic loader.
......@@ -387,34 +402,42 @@ template <class ELFT> static void createSyntheticSections() {
387402 // packing is enabled because that would cause a section type mismatch.
388403 // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
389404 // 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>>(
391406 (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
392407 ? ".rel.dyn"
393 : InX::RelaPlt->Name,
408 : In.RelaPlt->Name,
394409 false /*Sort*/);
395 Add(InX::RelaIplt);
396
397 InX::Plt = make<PltSection>(false);
398 Add(InX::Plt);
399 InX::Iplt = make<PltSection>(true);
400 Add(InX::Iplt);
410 Add(In.RelaIplt);
411
412 In.Plt = make<PltSection>(false);
413 Add(In.Plt);
414 In.Iplt = make<PltSection>(true);
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
402425 if (!Config->Relocatable) {
403426 if (Config->EhFrameHdr) {
404 InX::EhFrameHdr = make<EhFrameHeader>();
405 Add(InX::EhFrameHdr);
427 In.EhFrameHdr = make<EhFrameHeader>();
428 Add(In.EhFrameHdr);
406429 }
407 InX::EhFrame = make<EhFrameSection>();
408 Add(InX::EhFrame);
430 In.EhFrame = make<EhFrameSection>();
431 Add(In.EhFrame);
409432 }
410433
411 if (InX::SymTab)
412 Add(InX::SymTab);
413 if (InX::SymTabShndx)
414 Add(InX::SymTabShndx);
415 Add(InX::ShStrTab);
416 if (InX::StrTab)
417 Add(InX::StrTab);
434 if (In.SymTab)
435 Add(In.SymTab);
436 if (In.SymTabShndx)
437 Add(In.SymTabShndx);
438 Add(In.ShStrTab);
439 if (In.StrTab)
440 Add(In.StrTab);
418441
419442 if (Config->EMachine == EM_ARM && !Config->Relocatable)
420443 // Add a sentinel to terminate .ARM.exidx. It helps an unwinder
......@@ -451,6 +474,7 @@ template <class ELFT> void Writer<ELFT>::run() {
451474 // to the string table, and add entries to .got and .plt.
452475 // finalizeSections does that.
453476 finalizeSections();
477 checkExecuteOnly();
454478 if (errorCount())
455479 return;
456480
......@@ -476,10 +500,9 @@ template <class ELFT> void Writer<ELFT>::run() {
476500
477501 setPhdrs();
478502
479 if (Config->Relocatable) {
503 if (Config->Relocatable)
480504 for (OutputSection *Sec : OutputSections)
481505 Sec->Addr = 0;
482 }
483506
484507 if (Config->CheckSections)
485508 checkSections();
......@@ -548,9 +571,11 @@ static bool includeInSymtab(const Symbol &B) {
548571 if (!Sec)
549572 return true;
550573 Sec = Sec->Repl;
574
551575 // Exclude symbols pointing to garbage-collected sections.
552576 if (isa<InputSectionBase>(Sec) && !Sec->Live)
553577 return false;
578
554579 if (auto *S = dyn_cast<MergeInputSection>(Sec))
555580 if (!S->getSectionPiece(D->Value)->Live)
556581 return false;
......@@ -562,7 +587,7 @@ static bool includeInSymtab(const Symbol &B) {
562587// Local symbols are not in the linker's symbol table. This function scans
563588// each object file's symbol table to copy local symbols to the output.
564589template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
565 if (!InX::SymTab)
590 if (!In.SymTab)
566591 return;
567592 for (InputFile *File : ObjectFiles) {
568593 ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
......@@ -581,16 +606,16 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
581606 SectionBase *Sec = DR->Section;
582607 if (!shouldKeepInSymtab(Sec, B->getName(), *B))
583608 continue;
584 InX::SymTab->addSymbol(B);
609 In.SymTab->addSymbol(B);
585610 }
586611 }
587612}
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.
589618template <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.
594619 for (BaseCommand *Base : Script->SectionCommands) {
595620 auto *Sec = dyn_cast<OutputSection>(Base);
596621 if (!Sec)
......@@ -617,7 +642,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
617642 auto *Sym =
618643 make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
619644 /*Value=*/0, /*Size=*/0, IS);
620 InX::SymTab->addSymbol(Sym);
645 In.SymTab->addSymbol(Sym);
621646 }
622647}
623648
......@@ -662,9 +687,14 @@ static bool isRelroSection(const OutputSection *Sec) {
662687 // .got contains pointers to external symbols. They are resolved by
663688 // the dynamic linker when a module is loaded into memory, and after
664689 // 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())
666691 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.
668698 if (Sec->Name.equals(".toc"))
669699 return true;
670700
......@@ -672,13 +702,13 @@ static bool isRelroSection(const OutputSection *Sec) {
672702 // by default resolved lazily, so we usually cannot put it into RELRO.
673703 // However, if "-z now" is given, the lazy symbol resolution is
674704 // disabled, which enables us to put it into RELRO.
675 if (Sec == InX::GotPlt->getParent())
705 if (Sec == In.GotPlt->getParent())
676706 return Config->ZNow;
677707
678708 // .dynamic section contains data for the dynamic linker, and
679709 // there's no need to write to it at runtime, so it's better to put
680710 // it into RELRO.
681 if (Sec == InX::Dynamic->getParent())
711 if (Sec == In.Dynamic->getParent())
682712 return true;
683713
684714 // Sections with some special names are put into RELRO. This is a
......@@ -700,17 +730,17 @@ static bool isRelroSection(const OutputSection *Sec) {
700730// * It is easy two see how similar two ranks are (see getRankProximity).
701731enum RankFlags {
702732 RF_NOT_ADDR_SET = 1 << 18,
703 RF_NOT_INTERP = 1 << 17,
704 RF_NOT_ALLOC = 1 << 16,
705 RF_WRITE = 1 << 15,
706 RF_EXEC_WRITE = 1 << 14,
707 RF_EXEC = 1 << 13,
708 RF_RODATA = 1 << 12,
709 RF_NON_TLS_BSS = 1 << 11,
710 RF_NON_TLS_BSS_RO = 1 << 10,
711 RF_NOT_TLS = 1 << 9,
712 RF_BSS = 1 << 8,
713 RF_NOTE = 1 << 7,
733 RF_NOT_ALLOC = 1 << 17,
734 RF_NOT_INTERP = 1 << 16,
735 RF_NOT_NOTE = 1 << 15,
736 RF_WRITE = 1 << 14,
737 RF_EXEC_WRITE = 1 << 13,
738 RF_EXEC = 1 << 12,
739 RF_RODATA = 1 << 11,
740 RF_NON_TLS_BSS = 1 << 10,
741 RF_NON_TLS_BSS_RO = 1 << 9,
742 RF_NOT_TLS = 1 << 8,
743 RF_BSS = 1 << 7,
714744 RF_PPC_NOT_TOCBSS = 1 << 6,
715745 RF_PPC_TOCL = 1 << 5,
716746 RF_PPC_TOC = 1 << 4,
......@@ -729,16 +759,24 @@ static unsigned getSectionRank(const OutputSection *Sec) {
729759 return Rank;
730760 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
732767 // Put .interp first because some loaders want to see that section
733768 // on the first page of the executable file when loaded into memory.
734769 if (Sec->Name == ".interp")
735770 return Rank;
736771 Rank |= RF_NOT_INTERP;
737772
738 // Allocatable sections go first to reduce the total PT_LOAD size and
739 // so debug info doesn't change addresses in actual code.
740 if (!(Sec->Flags & SHF_ALLOC))
741 return Rank | RF_NOT_ALLOC;
773 // Put .note sections (which make up one PT_NOTE) at the beginning so that
774 // they are likely to be included in a core file even if core file size is
775 // limited. In particular, we want a .note.gnu.build-id and a .note.tag to be
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
743781 // Sort sections based on their access permission in the following
744782 // order: R, RX, RWX, RW. This order is based on the following
......@@ -802,12 +840,6 @@ static unsigned getSectionRank(const OutputSection *Sec) {
802840 if (IsNoBits)
803841 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
811843 // Some architectures have additional ordering restrictions for sections
812844 // within the same PT_LOAD.
813845 if (Config->EMachine == EM_PPC64) {
......@@ -850,8 +882,10 @@ static unsigned getSectionRank(const OutputSection *Sec) {
850882static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
851883 const OutputSection *A = cast<OutputSection>(ACmd);
852884 const OutputSection *B = cast<OutputSection>(BCmd);
885
853886 if (A->SortRank != B->SortRank)
854887 return A->SortRank < B->SortRank;
888
855889 if (!(A->SortRank & RF_NOT_ADDR_SET))
856890 return Config->SectionStartMap.lookup(A->Name) <
857891 Config->SectionStartMap.lookup(B->Name);
......@@ -874,14 +908,20 @@ void PhdrEntry::add(OutputSection *Sec) {
874908// need these symbols, since IRELATIVE relocs are resolved through GOT
875909// and PLT. For details, see http://www.airs.com/blog/archives/403.
876910template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
877 if (needsInterpSection())
911 if (Config->Relocatable || needsInterpSection())
878912 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";
883 ElfSym::RelaIpltEnd =
884 addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
914 // By default, __rela_iplt_{start,end} belong to a dummy section 0
915 // because .rela.plt might be empty and thus removed from output.
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);
885925}
886926
887927template <class ELFT>
......@@ -895,7 +935,7 @@ void Writer<ELFT>::forEachRelSec(
895935 for (InputSectionBase *IS : InputSections)
896936 if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
897937 Fn(*IS);
898 for (EhInputSection *ES : InX::EhFrame->Sections)
938 for (EhInputSection *ES : In.EhFrame->Sections)
899939 Fn(*ES);
900940}
901941
......@@ -908,15 +948,19 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
908948 if (ElfSym::GlobalOffsetTable) {
909949 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
910950 // to the start of the .got or .got.plt section.
911 InputSection *GotSection = InX::GotPlt;
951 InputSection *GotSection = In.GotPlt;
912952 if (!Target->GotBaseSymInGotPlt)
913 GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
914 : cast<InputSection>(InX::Got);
953 GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
954 : cast<InputSection>(In.Got);
915955 ElfSym::GlobalOffsetTable->Section = GotSection;
916956 }
917957
918 if (ElfSym::RelaIpltEnd)
919 ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize();
958 // .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
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
921965 PhdrEntry *Last = nullptr;
922966 PhdrEntry *LastRO = nullptr;
......@@ -1088,7 +1132,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
10881132 SymbolOrderEntry &Ent = It->second;
10891133 Ent.Present = true;
10901134
1091 warnUnorderableSymbol(&Sym);
1135 maybeWarnUnorderableSymbol(&Sym);
10921136
10931137 if (auto *D = dyn_cast<Defined>(&Sym)) {
10941138 if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
......@@ -1097,6 +1141,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
10971141 }
10981142 }
10991143 };
1144
11001145 // We want both global and local symbols. We get the global ones from the
11011146 // symbol table and iterate the object files for the local ones.
11021147 for (Symbol *Sym : Symtab->getSymbols())
......@@ -1132,11 +1177,10 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
11321177 }
11331178 OrderedSections.push_back({IS, I->second});
11341179 }
1135 llvm::sort(
1136 OrderedSections.begin(), OrderedSections.end(),
1137 [&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) {
1138 return A.second < B.second;
1139 });
1180 llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A,
1181 std::pair<InputSection *, int> B) {
1182 return A.second < B.second;
1183 });
11401184
11411185 // Find an insertion point for the ordered section list in the unordered
11421186 // section list. On targets with limited-range branches, this is the mid-point
......@@ -1166,7 +1210,7 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
11661210 // we effectively double the amount of code that could potentially call into
11671211 // the hot code without a thunk.
11681212 size_t InsPt = 0;
1169 if (Target->ThunkSectionSpacing && !OrderedSections.empty()) {
1213 if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
11701214 uint64_t UnorderedPos = 0;
11711215 for (; InsPt != UnorderedSections.size(); ++InsPt) {
11721216 UnorderedPos += UnorderedSections[InsPt]->getSize();
......@@ -1342,10 +1386,12 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {
13421386 if (A->kind() == InputSectionBase::Synthetic ||
13431387 B->kind() == InputSectionBase::Synthetic)
13441388 return A->kind() != InputSectionBase::Synthetic;
1389
13451390 InputSection *LA = A->getLinkOrderDep();
13461391 InputSection *LB = B->getLinkOrderDep();
13471392 OutputSection *AOut = LA->getParent();
13481393 OutputSection *BOut = LB->getParent();
1394
13491395 if (AOut != BOut)
13501396 return AOut->SectionIndex < BOut->SectionIndex;
13511397 return LA->OutSecOff < LB->OutSecOff;
......@@ -1392,6 +1438,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
13921438 for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())
13931439 if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
13941440 return false;
1441
13951442 // All table entries in this .ARM.exidx Section can be merged into the
13961443 // previous Section.
13971444 return true;
......@@ -1423,18 +1470,19 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
14231470 assert(Sections.size() >= 2 &&
14241471 "We should create a sentinel section only if there are "
14251472 "alive regular exidx sections.");
1473
14261474 // The last executable section is required to fill the sentinel.
14271475 // Remember it here so that we don't have to find it again.
14281476 Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();
14291477 }
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.
14311485 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.
14381486 size_t Prev = 0;
14391487 // The last one is a sentinel entry which should not be removed.
14401488 for (size_t I = 1; I < Sections.size() - 1; ++I) {
......@@ -1456,11 +1504,49 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
14561504 }
14571505}
14581506
1459static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
1460 llvm::function_ref<void(SyntheticSection *)> Fn) {
1461 for (SyntheticSection *SS : Sections)
1462 if (SS && SS->getParent() && !SS->empty())
1463 Fn(SS);
1507// For most RISC ISAs, we need to generate content that depends on the address
1508// of InputSections. For example some architectures such as AArch64 use small
1509// displacements for jump instructions that is the linker's responsibility for
1510// creating range extension thunks for. As the generation of the content may
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();
14641550}
14651551
14661552// In order to allow users to manipulate linker-synthesized sections,
......@@ -1500,6 +1586,7 @@ static void removeUnusedSyntheticSections() {
15001586// with the same name defined in other ELF executable or DSO.
15011587static bool computeIsPreemptible(const Symbol &B) {
15021588 assert(!B.isLocal());
1589
15031590 // Only symbols that appear in dynsym can be preempted.
15041591 if (!B.includeInDynsym())
15051592 return false;
......@@ -1528,7 +1615,6 @@ static bool computeIsPreemptible(const Symbol &B) {
15281615
15291616// Create output section objects and add them to OutputSections.
15301617template <class ELFT> void Writer<ELFT>::finalizeSections() {
1531 Out::DebugInfo = findSection(".debug_info");
15321618 Out::PreinitArray = findSection(".preinit_array");
15331619 Out::InitArray = findSection(".init_array");
15341620 Out::FiniArray = findSection(".fini_array");
......@@ -1547,46 +1633,51 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
15471633 // It should be okay as no one seems to care about the type.
15481634 // Even the author of gold doesn't remember why gold behaves that way.
15491635 // https://sourceware.org/ml/binutils/2002-03/msg00360.html
1550 if (InX::DynSymTab)
1551 Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
1552 /*Size=*/0, STB_WEAK, InX::Dynamic,
1636 if (In.Dynamic->Parent)
1637 Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
1638 /*Size=*/0, STB_WEAK, In.Dynamic,
15531639 /*File=*/nullptr);
15541640
15551641 // Define __rel[a]_iplt_{start,end} symbols if needed.
15561642 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
15581649 // This responsible for splitting up .eh_frame section into
15591650 // pieces. The relocation scan uses those pieces, so this has to be
15601651 // earlier.
1561 applySynthetic({InX::EhFrame},
1562 [](SyntheticSection *SS) { SS->finalizeContents(); });
1652 finalizeSynthetic(In.EhFrame);
15631653
15641654 for (Symbol *S : Symtab->getSymbols())
1565 S->IsPreemptible |= computeIsPreemptible(*S);
1655 if (!S->IsPreemptible)
1656 S->IsPreemptible = computeIsPreemptible(*S);
15661657
15671658 // Scan relocations. This must be done after every symbol is declared so that
15681659 // we can correctly decide if a dynamic relocation is needed.
15691660 if (!Config->Relocatable)
15701661 forEachRelSec(scanRelocations<ELFT>);
15711662
1572 if (InX::Plt && !InX::Plt->empty())
1573 InX::Plt->addSymbols();
1574 if (InX::Iplt && !InX::Iplt->empty())
1575 InX::Iplt->addSymbols();
1663 if (In.Plt && !In.Plt->empty())
1664 In.Plt->addSymbols();
1665 if (In.Iplt && !In.Iplt->empty())
1666 In.Iplt->addSymbols();
15761667
15771668 // Now that we have defined all possible global symbols including linker-
15781669 // synthesized ones. Visit all symbols to give the finishing touches.
15791670 for (Symbol *Sym : Symtab->getSymbols()) {
15801671 if (!includeInSymtab(*Sym))
15811672 continue;
1582 if (InX::SymTab)
1583 InX::SymTab->addSymbol(Sym);
1673 if (In.SymTab)
1674 In.SymTab->addSymbol(Sym);
15841675
1585 if (InX::DynSymTab && Sym->includeInDynsym()) {
1586 InX::DynSymTab->addSymbol(Sym);
1676 if (Sym->includeInDynsym()) {
1677 In.DynSymTab->addSymbol(Sym);
15871678 if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
15881679 if (File->IsNeeded && !Sym->isUndefined())
1589 In<ELFT>::VerNeed->addSymbol(Sym);
1680 InX<ELFT>::VerNeed->addSymbol(Sym);
15901681 }
15911682 }
15921683
......@@ -1594,8 +1685,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
15941685 if (errorCount())
15951686 return;
15961687
1597 if (InX::MipsGot)
1598 InX::MipsGot->build<ELFT>();
1688 if (In.MipsGot)
1689 In.MipsGot->build<ELFT>();
15991690
16001691 removeUnusedSyntheticSections();
16011692
......@@ -1607,15 +1698,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16071698 if (auto *Sec = dyn_cast<OutputSection>(Base))
16081699 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
16191701 // Prefer command line supplied address over other constraints.
16201702 for (OutputSection *Sec : OutputSections) {
16211703 auto I = Config->SectionStartMap.find(Sec->Name);
......@@ -1628,10 +1710,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16281710 // particularly relevant.
16291711 Out::ElfHeader->SectionIndex = 1;
16301712
1631 unsigned I = 1;
1632 for (OutputSection *Sec : OutputSections) {
1633 Sec->SectionIndex = I++;
1634 Sec->ShName = InX::ShStrTab->addString(Sec->Name);
1713 for (size_t I = 0, E = OutputSections.size(); I != E; ++I) {
1714 OutputSection *Sec = OutputSections[I];
1715 Sec->SectionIndex = I + 1;
1716 Sec->ShName = In.ShStrTab->addString(Sec->Name);
16351717 }
16361718
16371719 // Binary and relocatable output does not have PHDRS.
......@@ -1641,6 +1723,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16411723 Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
16421724 addPtArmExid(Phdrs);
16431725 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;
16441732 }
16451733
16461734 // Some symbols are defined in term of program headers. Now that we
......@@ -1649,15 +1737,30 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16491737
16501738 // Dynamic section must be the last one in this list and dynamic
16511739 // symbol table section (DynSymTab) must be the first one.
1652 applySynthetic(
1653 {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab,
1654 InX::HashTab, InX::SymTab, InX::SymTabShndx, InX::ShStrTab,
1655 InX::StrTab, In<ELFT>::VerDef, InX::DynStrTab, InX::Got,
1656 InX::MipsGot, InX::IgotPlt, InX::GotPlt, InX::RelaDyn,
1657 InX::RelrDyn, InX::RelaIplt, InX::RelaPlt, InX::Plt,
1658 InX::Iplt, InX::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed,
1659 InX::Dynamic},
1660 [](SyntheticSection *SS) { SS->finalizeContents(); });
1740 finalizeSynthetic(In.DynSymTab);
1741 finalizeSynthetic(In.Bss);
1742 finalizeSynthetic(In.BssRelRo);
1743 finalizeSynthetic(In.GnuHashTab);
1744 finalizeSynthetic(In.HashTab);
1745 finalizeSynthetic(In.SymTabShndx);
1746 finalizeSynthetic(In.ShStrTab);
1747 finalizeSynthetic(In.StrTab);
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
16621765 if (!Script->HasSectionsCommand && !Config->Relocatable)
16631766 fixSectionAlignments();
......@@ -1666,37 +1769,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16661769 // needs to be resolved before any other address dependent operation.
16671770 resolveShfLinkOrder();
16681771
1669 // Some architectures need to generate content that depends on the address
1670 // of InputSections. For example some architectures use small displacements
1671 // for jump instructions that is the linker's responsibility for creating
1672 // range extension thunks for. As the generation of the content may also
1673 // alter InputSection addresses we must converge to a fixed point.
1674 if (Target->NeedsThunks || Config->AndroidPackDynRelocs ||
1675 Config->RelrPackDynRelocs) {
1676 ThunkCreator TC;
1677 AArch64Err843419Patcher A64P;
1678 bool Changed;
1679 do {
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 }
1772 // Jump instructions in many ISAs have small displacements, and therefore they
1773 // cannot jump to arbitrary addresses in memory. For example, RISC-V JAL
1774 // instruction can target only +-1 MiB from PC. It is a linker's
1775 // responsibility to create and insert small pieces of code between sections
1776 // to extend the ranges if jump targets are out of range. Such code pieces are
1777 // called "thunks".
1778 //
1779 // We add thunks at this stage. We couldn't do this before this point because
1780 // this is the earliest point where we know sizes of sections and their
1781 // layouts (that are needed to determine if jump targets are in range).
1782 maybeAddThunks();
16961783
1697 // createThunks may have added local symbols to the static symbol table
1698 applySynthetic({InX::SymTab},
1699 [](SyntheticSection *SS) { SS->postThunkContents(); });
1784 // maybeAddThunks may have added local symbols to the static symbol table.
1785 finalizeSynthetic(In.SymTab);
1786 finalizeSynthetic(In.PPC64LongBranchTarget);
17001787
17011788 // Fill other section headers. The dynamic table is finalized
17021789 // at the end because some tags like RELSZ depend on result
......@@ -1705,6 +1792,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17051792 Sec->finalize<ELFT>();
17061793}
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
17081810// The linker is expected to define SECNAME_start and SECNAME_end
17091811// symbols for a few sections. This function defines them.
17101812template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
......@@ -1721,9 +1823,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
17211823 // program to fail to link due to relocation overflow, if their
17221824 // program text is above 2 GiB. We use the address of the .text
17231825 // 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.
17241829 OutputSection *Default = findSection(".text");
17251830 if (!Default)
17261831 Default = Out::ElfHeader;
1832
17271833 auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
17281834 if (OS) {
17291835 addOptionalRegular(Start, OS, 0);
......@@ -1763,7 +1869,7 @@ static bool needsPtLoad(OutputSection *Sec) {
17631869 // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
17641870 // responsible for allocating space for them, not the PT_LOAD that
17651871 // 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)
17671873 return false;
17681874 return true;
17691875}
......@@ -1841,9 +1947,8 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
18411947 Ret.push_back(TlsHdr);
18421948
18431949 // Add an entry for .dynamic.
1844 if (InX::DynSymTab)
1845 AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
1846 ->add(InX::Dynamic->getParent());
1950 if (OutputSection *Sec = In.Dynamic->getParent())
1951 AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
18471952
18481953 // PT_GNU_RELRO includes all sections that should be marked as
18491954 // read-only by dynamic linker after proccessing relocations.
......@@ -1871,10 +1976,10 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
18711976 Ret.push_back(RelRo);
18721977
18731978 // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
1874 if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() &&
1875 InX::EhFrameHdr->getParent())
1876 AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags())
1877 ->add(InX::EhFrameHdr->getParent());
1979 if (!In.EhFrame->empty() && In.EhFrameHdr && In.EhFrame->getParent() &&
1980 In.EhFrameHdr->getParent())
1981 AddHdr(PT_GNU_EH_FRAME, In.EhFrameHdr->getParent()->getPhdrFlags())
1982 ->add(In.EhFrameHdr->getParent());
18781983
18791984 // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
18801985 // the dynamic linker fill the segment with random data.
......@@ -1945,77 +2050,77 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
19452050 for (const PhdrEntry *P : Phdrs) {
19462051 if (P->p_type != PT_GNU_RELRO)
19472052 continue;
2053
19482054 if (P->FirstSec)
19492055 PageAlign(P->FirstSec);
2056
19502057 // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
19512058 // have to align it to a page.
19522059 auto End = OutputSections.end();
19532060 auto I = std::find(OutputSections.begin(), End, P->LastSec);
19542061 if (I == End || (I + 1) == End)
19552062 continue;
2063
19562064 OutputSection *Cmd = (*(I + 1));
19572065 if (needsPtLoad(Cmd))
19582066 PageAlign(Cmd);
19592067 }
19602068}
19612069
1962// Adjusts the file alignment for a given output section and returns
1963// its new file offset. The file offset must be the same with its
1964// virtual address (modulo the page size) so that the loader can load
1965// executables without any address adjustment.
1966static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) {
1967 OutputSection *First = Cmd->PtLoad ? Cmd->PtLoad->FirstSec : nullptr;
1968 // The first section in a PT_LOAD has to have congruent offset and address
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)
2070// Compute an in-file position for a given section. The file offset must be the
2071// same with its virtual address modulo the page size, so that the loader can
2072// load executables without any address adjustment.
2073static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) {
2074 // File offsets are not significant for .bss sections. By convention, we keep
2075 // section offsets monotonically increasing rather than setting to zero.
2076 if (OS->Type == SHT_NOBITS)
19782077 return Off;
19792078
19802079 // If the section is not in a PT_LOAD, we just have to align it.
1981 if (!Cmd->PtLoad)
1982 return alignTo(Off, Cmd->Alignment);
2080 if (!OS->PtLoad)
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
19842091 // If two sections share the same PT_LOAD the file offset is calculated
19852092 // using this formula: Off2 = Off1 + (VA2 - VA1).
1986 return First->Offset + Cmd->Addr - First->Addr;
2093 return First->Offset + OS->Addr - First->Addr;
19872094}
19882095
1989static uint64_t setOffset(OutputSection *Cmd, uint64_t Off) {
1990 Off = getFileAlignment(Off, Cmd);
1991 Cmd->Offset = Off;
2096// Set an in-file position to a given section and returns the end position of
2097// the section.
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.
1994 if (Cmd->Type == SHT_NOBITS)
2102 if (OS->Type == SHT_NOBITS)
19952103 return Off;
1996
1997 return Off + Cmd->Size;
2104 return Off + OS->Size;
19982105}
19992106
20002107template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
20012108 uint64_t Off = 0;
20022109 for (OutputSection *Sec : OutputSections)
20032110 if (Sec->Flags & SHF_ALLOC)
2004 Off = setOffset(Sec, Off);
2111 Off = setFileOffset(Sec, Off);
20052112 FileSize = alignTo(Off, Config->Wordsize);
20062113}
20072114
20082115static std::string rangeToString(uint64_t Addr, uint64_t Len) {
2009 if (Len == 0)
2010 return "<empty range at 0x" + utohexstr(Addr) + ">";
20112116 return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
20122117}
20132118
20142119// Assign file offsets to output sections.
20152120template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
20162121 uint64_t Off = 0;
2017 Off = setOffset(Out::ElfHeader, Off);
2018 Off = setOffset(Out::ProgramHeaders, Off);
2122 Off = setFileOffset(Out::ElfHeader, Off);
2123 Off = setFileOffset(Out::ProgramHeaders, Off);
20192124
20202125 PhdrEntry *LastRX = nullptr;
20212126 for (PhdrEntry *P : Phdrs)
......@@ -2023,9 +2128,10 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
20232128 LastRX = P;
20242129
20252130 for (OutputSection *Sec : OutputSections) {
2026 Off = setOffset(Sec, Off);
2131 Off = setFileOffset(Sec, Off);
20272132 if (Script->HasSectionsCommand)
20282133 continue;
2134
20292135 // If this is a last section of the last executable segment and that
20302136 // segment is the last loadable segment, align the offset of the
20312137 // following section to avoid loading non-segments parts of the file.
......@@ -2050,7 +2156,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
20502156 continue;
20512157 if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
20522158 error("unable to place section " + Sec->Name + " at file offset " +
2053 rangeToString(Sec->Offset, Sec->Offset + Sec->Size) +
2159 rangeToString(Sec->Offset, Sec->Size) +
20542160 "; check your linker script for overflows");
20552161 }
20562162}
......@@ -2061,19 +2167,23 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
20612167 for (PhdrEntry *P : Phdrs) {
20622168 OutputSection *First = P->FirstSec;
20632169 OutputSection *Last = P->LastSec;
2170
20642171 if (First) {
20652172 P->p_filesz = Last->Offset - First->Offset;
20662173 if (Last->Type != SHT_NOBITS)
20672174 P->p_filesz += Last->Size;
2175
20682176 P->p_memsz = Last->Addr + Last->Size - First->Addr;
20692177 P->p_offset = First->Offset;
20702178 P->p_vaddr = First->Addr;
2179
20712180 if (!P->HasLMA)
20722181 P->p_paddr = First->getLMA();
20732182 }
2074 if (P->p_type == PT_LOAD)
2183
2184 if (P->p_type == PT_LOAD) {
20752185 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) {
20772187 P->p_align = 1;
20782188 // The glibc dynamic loader rounds the size down, so we need to round up
20792189 // 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() {
20812191 P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
20822192 }
20832193
2084 // The TLS pointer goes after PT_TLS. At least glibc will align it,
2085 // so round up the size to make sure the offsets are correct.
2086 if (P->p_type == PT_TLS) {
2087 Out::TlsPhdr = P;
2088 if (P->p_memsz)
2089 P->p_memsz = alignTo(P->p_memsz, P->p_align);
2194 if (P->p_type == PT_TLS && P->p_memsz) {
2195 if (!Config->Shared &&
2196 (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) {
2197 // On ARM/AArch64, reserve extra space (8 words) between the thread
2198 // pointer and an executable's TLS segment by overaligning the segment.
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);
20902210 }
20912211 }
20922212}
......@@ -2103,10 +2223,9 @@ struct SectionOffset {
21032223// load and virtual adresses).
21042224static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
21052225 bool IsVirtualAddr) {
2106 llvm::sort(Sections.begin(), Sections.end(),
2107 [=](const SectionOffset &A, const SectionOffset &B) {
2108 return A.Offset < B.Offset;
2109 });
2226 llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) {
2227 return A.Offset < B.Offset;
2228 });
21102229
21112230 // Finding overlap is easy given a vector is sorted by start position.
21122231 // If an element starts before the end of the previous element, they overlap.
......@@ -2150,7 +2269,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
21502269 // file so we skip any non-allocated sections in that case.
21512270 std::vector<SectionOffset> FileOffs;
21522271 for (OutputSection *Sec : OutputSections)
2153 if (0 < Sec->Size && Sec->Type != SHT_NOBITS &&
2272 if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&
21542273 (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
21552274 FileOffs.push_back({Sec, Sec->Offset});
21562275 checkOverlap("file", FileOffs, false);
......@@ -2168,7 +2287,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
21682287 // ranges in the file.
21692288 std::vector<SectionOffset> VMAs;
21702289 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))
21722291 VMAs.push_back({Sec, Sec->Addr});
21732292 checkOverlap("virtual address", VMAs, true);
21742293
......@@ -2177,7 +2296,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
21772296 // script with AT().
21782297 std::vector<SectionOffset> LMAs;
21792298 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))
21812300 LMAs.push_back({Sec, Sec->getLMA()});
21822301 checkOverlap("load address", LMAs, false);
21832302}
......@@ -2190,7 +2309,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
21902309// 4. the number represented by the entry symbol, if it is a number;
21912310// 5. the address of the first byte of the .text section, if present;
21922311// 6. the address 0.
2193template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {
2312static uint64_t getEntryAddr() {
21942313 // Case 1, 2 or 3
21952314 if (Symbol *B = Symtab->find(Config->Entry))
21962315 return B->getVA();
......@@ -2233,6 +2352,7 @@ static uint8_t getAbiVersion() {
22332352
22342353template <class ELFT> void Writer<ELFT>::writeHeader() {
22352354 uint8_t *Buf = Buffer->getBufferStart();
2355
22362356 // For executable segments, the trap instructions are written before writing
22372357 // the header. Setting Elf header bytes to zero ensures that any unused bytes
22382358 // in header are zero-cleared, instead of having trap instructions.
......@@ -2291,7 +2411,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
22912411 else
22922412 EHdr->e_shnum = Num;
22932413
2294 uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex;
2414 uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
22952415 if (StrTabIndex >= SHN_LORESERVE) {
22962416 SHdrs->sh_link = StrTabIndex;
22972417 EHdr->e_shstrndx = SHN_XINDEX;
......@@ -2305,7 +2425,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
23052425
23062426// Open a result file.
23072427template <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) {
23092430 error("output file too large: " + Twine(FileSize) + " bytes");
23102431 return;
23112432 }
......@@ -2370,8 +2491,8 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
23702491 uint8_t *Buf = Buffer->getBufferStart();
23712492
23722493 OutputSection *EhFrameHdr = nullptr;
2373 if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
2374 EhFrameHdr = InX::EhFrameHdr->getParent();
2494 if (In.EhFrameHdr && !In.EhFrameHdr->empty())
2495 EhFrameHdr = In.EhFrameHdr->getParent();
23752496
23762497 // In -r or -emit-relocs mode, write the relocation sections first as in
23772498 // 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() {
23912512}
23922513
23932514template <class ELFT> void Writer<ELFT>::writeBuildId() {
2394 if (!InX::BuildId || !InX::BuildId->getParent())
2515 if (!In.BuildId || !In.BuildId->getParent())
23952516 return;
23962517
23972518 // Compute a hash of all sections of the output file.
23982519 uint8_t *Start = Buffer->getBufferStart();
23992520 uint8_t *End = Start + FileSize;
2400 InX::BuildId->writeBuildId({Start, End});
2521 In.BuildId->writeBuildId({Start, End});
24012522}
24022523
24032524template void elf::writeResult<ELF32LE>();
deps/lld/LICENSE.TXT+1-1
......@@ -4,7 +4,7 @@ lld License
44University of Illinois/NCSA
55Open Source License
66
7Copyright (c) 2011-2018 by the contributors listed in CREDITS.TXT
7Copyright (c) 2011-2019 by the contributors listed in CREDITS.TXT
88All rights reserved.
99
1010Developed by:
deps/lld/MinGW/Driver.cpp+27-4
......@@ -6,9 +6,27 @@
66// License. See LICENSE.TXT for details.
77//
88//===----------------------------------------------------------------------===//
9///
10/// GNU ld style linker driver for COFF currently supporting mingw-w64.
11///
9//
10// MinGW is a GNU development environment for Windows. It consists of GNU
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//
1230//===----------------------------------------------------------------------===//
1331
1432#include "lld/Common/Driver.h"
......@@ -212,9 +230,14 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
212230 else
213231 Add("-alternatename:__image_base__=__ImageBase");
214232
233 for (auto *A : Args.filtered(OPT_require_defined))
234 Add("-include:" + StringRef(A->getValue()));
235
215236 std::vector<StringRef> SearchPaths;
216 for (auto *A : Args.filtered(OPT_L))
237 for (auto *A : Args.filtered(OPT_L)) {
217238 SearchPaths.push_back(A->getValue());
239 Add("-libpath:" + StringRef(A->getValue()));
240 }
218241
219242 StringRef Prefix = "";
220243 bool Static = false;
deps/lld/MinGW/Options.td+9
......@@ -40,6 +40,9 @@ def strip_debug: F<"strip-debug">,
4040def whole_archive: F<"whole-archive">,
4141 HelpText<"Include all object files for following archives">;
4242def 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
4447// LLD specific options
4548def _HASH_HASH_HASH : Flag<["-"], "###">,
......@@ -75,3 +78,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">;
7578def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
7679def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
7780def 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.
5353 until we need them to continue linking.
5454 When we need to do some costly operation (such as looking up
5555 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)
5757 on the first operation and use it throughout the process.
5858
5959* Efficient archive file handling
......@@ -90,18 +90,18 @@ between speed, simplicity and extensibility.
9090 `--end-group`, to let the linker loop over the files between the options until
9191 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
9595 Here is how LLD approaches the problem. Instead of memorizing only undefined
9696 symbols, we program LLD so that it memorizes all symbols. When it sees an
9797 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 link
99 it. It is doable because LLD does not forget symbols it have seen in archive
98 archive file it previously visited, it immediately extracts the file and links
99 it. It is doable because LLD does not forget symbols it has seen in archive
100100 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 traditional
104 The semantics of LLD's archive handling are different from the traditional
105105 Unix's. You can observe it if you carefully craft archive files to exploit
106106 it. However, in reality, we don't know any program that cannot link with our
107107 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.
157157 - Undefined symbols represent undefined symbols, which need to be replaced by
158158 Defined symbols by the resolver until the link is complete.
159159 - 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
162162 There's only one Symbol instance for each unique symbol name. This uniqueness
163163 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.
66
77We currently use the 'nature' theme and a Beaker inspired structure.
88
9To rebuild documents into html:
10
11 [/lld/docs]> make html
12
9See sphinx_intro.rst for more details.
deps/lld/docs/Readers.rst+1-1
......@@ -74,7 +74,7 @@ files in parallel. Therefore, there should be no parsing state in you Reader
7474object. Any parsing state should be in ivars of your File subclass or in
7575some temporary object.
7676
77The key method to implement in a reader is::
77The key function to implement in a reader is::
7878
7979 virtual error_code loadFile(LinkerInput &input,
8080 std::vector<std::unique_ptr<File>> &result);
deps/lld/docs/ReleaseNotes.rst+80-12
......@@ -1,14 +1,19 @@
11=======================
2LLD 7.0.0 Release Notes
2lld 8.0.0 Release Notes
33=======================
44
55.. contents::
66 :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
813Introduction
914============
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.
1217Here we describe the status of lld, including major improvements
1318from the previous release. All lld releases may be downloaded
1419from the `LLVM releases web site <https://llvm.org/releases/>`_.
......@@ -19,23 +24,86 @@ Non-comprehensive list of changes in this release
1924ELF Improvements
2025----------------
2126
22* lld is now able to overcome MIPS GOT entries number limitation
23 and generate multi-GOT if necessary.
27* lld now supports RISC-V. (`r339364
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 relocations
30 in case of relocatable output.
43* lld now uses the ``sigrie`` instruction as a trap instruction for
44 MIPS targets.
3145
3246COFF Improvements
3347-----------------
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 @@
11WebAssembly lld port
22====================
33
4Note: The WebAssembly port is still a work in progress and is be lacking
5certain features.
6
74The 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 mimic
9the behaviour of traditional ELF linkers and specifically the ELF lld port.
10Where possible that command line flags and the semantics should be the same.
5a WebAssembly binary as its output. For the most part it tries to mimic the
6behaviour of traditional ELF linkers and specifically the ELF lld port. Where
7possible that command line flags and the semantics should be the same.
118
129
1310Object file format
......@@ -23,14 +20,95 @@ currently requires enabling the experimental backed using
2320``-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
26107Missing features
27108----------------
28109
29There are several key features that are not yet implement in the WebAssembly
30ports:
31
32- COMDAT support. This means that support for C++ is still very limited.
33- Function stripping. Currently there is no support for ``--gc-sections`` so
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.
110- Merging of data section similar to ``SHF_MERGE`` in the ELF world is not
111 supported.
112- No support for creating shared libraries. The spec for shared libraries in
113 WebAssembly is still in flux:
114 https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
deps/lld/docs/conf.py+2-2
......@@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year
4848# built documents.
4949#
5050# The short version.
51version = '7'
51version = '8'
5252# The full version, including alpha/beta/rc tags.
53release = '7'
53release = '8'
5454
5555# The language for content autogenerated by Sphinx. Refer to documentation
5656# for a list of supported languages.
deps/lld/docs/index.rst+10-11
......@@ -1,7 +1,7 @@
11LLD - The LLVM Linker
22=====================
33
4LLD is a linker from the LLVM project. That is a drop-in replacement
4LLD is a linker from the LLVM project that is a drop-in replacement
55for system linkers and runs much faster than them. It also provides
66features that are useful for toolchain developers.
77
......@@ -17,7 +17,7 @@ read :doc:`AtomLLD`.
1717Features
1818--------
1919
20- LLD is a drop-in replacement for the GNU linkers. That accepts the
20- LLD is a drop-in replacement for the GNU linkers that accepts the
2121 same command line arguments and linker scripts as GNU.
2222
2323 We are currently working closely with the FreeBSD project to make
......@@ -30,29 +30,27 @@ Features
3030 <https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.
3131
3232- 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 GNU
33 machine, you can expect that LLD runs more than twice as fast as the GNU
3434 gold linker. Your milage may vary, though.
3535
3636- It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,
3737 ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.
38 Among these, x86-64 is the most well-supported target and have
39 reached production quality. AArch64 and MIPS seem decent too. x86
40 should be OK but not well tested yet. ARM support is being developed
41 actively.
38 Among these, x86-64, AArch64, and ARM (>= v6) are production quality.
39 MIPS seems decent too. x86 should be OK but is not well tested yet.
4240
4341- It is always a cross-linker, meaning that it always supports all the
4442 above targets however it was built. In fact, we don't provide a
4543 build-time option to enable/disable each target. This should make it
4644 easy to use our linker as part of a cross-compile toolchain.
4745
48- You can embed LLD to your program to eliminate dependency to
46- You can embed LLD in your program to eliminate dependencies on
4947 external linkers. All you have to do is to construct object files
5048 and command line arguments just like you would do to invoke an
5149 external linker and then call the linker's main function,
5250 ``lld::elf::link``, from your code.
5351
5452- 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 February
53 files, so it is not a completely fair comparison, but as of February
5654 2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
5755 consists of 198k lines of C++ code.
5856
......@@ -102,8 +100,8 @@ under ``tools`` directory just like you probably did for clang. For the
102100details, see `Getting Started with the LLVM System
103101<http://llvm.org/docs/GettingStarted.html>`_.
104102
105If you haven't checkout out LLVM, the easiest way to build LLD is to
106checkout the entire LLVM projects/sub-projects from a git mirror and
103If you haven't checked out LLVM, the easiest way to build LLD is to
104check out the entire LLVM projects/sub-projects from a git mirror and
107105build that tree. You need `cmake` and of course a C++ compiler.
108106
109107.. code-block:: console
......@@ -175,4 +173,5 @@ document soon.
175173 AtomLLD
176174 WebAssembly
177175 windows_support
176 missingkeyfunction
178177 ReleaseNotes
deps/lld/docs/ld.lld.1+53-4
......@@ -3,7 +3,7 @@
33.\"
44.\" This man page documents only lld's ELF linking support, obtained originally
55.\" from FreeBSD.
6.Dd July 30, 2018
6.Dd September 26, 2018
77.Dt LD.LLD 1
88.Os
99.Sh NAME
......@@ -13,6 +13,7 @@
1313.Nm ld.lld
1414.Op Ar options
1515.Ar objfile ...
16
1617.Sh DESCRIPTION
1718A linker takes one or more object, archive, and library files, and combines
1819them 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.
2526It accepts most of the same command line arguments and linker scripts
2627as GNU linkers.
2728.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
2944.Bl -tag -width indent
3045.It Fl -allow-multiple-definition
3146Do not error if a symbol is defined multiple times.
......@@ -144,6 +159,9 @@ Maximum number of errors to emit before stopping.
144159A value of zero indicates that there is no limit.
145160.It Fl -error-unresolved-symbols
146161Report unresolved symbols as errors.
162.It Fl -execute-only
163Mark executable sections unreadable. This option is currently only
164supported on AArch64.
147165.It Fl -exclude-libs Ns = Ns Ar value
148166Exclude static libraries from automatic export.
149167.It Fl -export-dynamic , Fl E
......@@ -293,10 +311,14 @@ Write optimization remarks in YAML format to
293311.Ar file .
294312.It Fl -opt-remarks-with-hotness
295313Include hotness information in the optimization remarks file.
314.It Fl -pic-veneer
315Always generate position independent thunks.
296316.It Fl -pie
297317Create a position independent executable.
298318.It Fl -print-gc-sections
299319List removed unused sections.
320.It Fl -print-icf-sections
321List identical folded sections.
300322.It Fl -print-map
301323Print a link map to the standard output.
302324.It Fl -push-state
......@@ -304,7 +326,7 @@ Save the current state of
304326.Fl -as-needed ,
305327.Fl -static ,
306328and
307.Fl -while-archive.
329.Fl -whole-archive.
308330.It Fl -pop-state
309331Undo the effect of
310332.Fl -push-state.
......@@ -426,6 +448,17 @@ This can be used to ensure linker invocation remains compatible with
426448traditional Unix-like linkers.
427449.It Fl -warn-common
428450Warn 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.
429462.It Fl -warn-unresolved-symbols
430463Report unresolved symbols as warnings.
431464.It Fl -whole-archive
......@@ -440,10 +473,22 @@ Make the main stack executable.
440473Stack permissions are recorded in the
441474.Dv PT_GNU_STACK
442475segment.
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.
443482.It Cm initfirst
444483Sets the
445484.Dv DF_1_INITFIRST
446485flag 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.
447492.It Cm muldefs
448493Do not error if a symbol is defined multiple times.
449494The first definition will be used.
......@@ -453,6 +498,10 @@ This is a synonym for
453498Disable combining and sorting multiple relocation sections.
454499.It Cm nocopyreloc
455500Disable 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.
456505.It Cm nodelete
457506Set the
458507.Dv DF_1_NODELETE
......@@ -460,7 +509,7 @@ flag to indicate that the object cannot be unloaded from a process.
460509.It Cm nodlopen
461510Set the
462511.Dv DF_1_NOOPEN
463flag to indcate that the object may not be opened by
512flag to indicate that the object may not be opened by
464513.Xr dlopen 3 .
465514.It Cm norelro
466515Do 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 @@
33Open Projects
44=============
55
6.. include:: ../include/lld/Core/TODO.txt
7
86Documentation TODOs
97~~~~~~~~~~~~~~~~~~~
108
deps/lld/docs/windows_support.rst+2-2
......@@ -20,8 +20,8 @@ command line options, and it drives further linking processes. LLD accepts
2020almost all command line options that the linker shipped with Microsoft Visual
2121C++ (link.exe) supports.
2222
23The current status is that LLD can link itself on Windows x86/x64
24using Visual C++ 2013 as the compiler.
23The current status is that LLD is used to link production builds of large
24real-world binaries such as Firefox and Chromium.
2525
2626Development status
2727==================
deps/lld/include/lld/Common/Args.h+3
......@@ -29,6 +29,9 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
2929 uint64_t Default);
3030
3131std::vector<StringRef> getLines(MemoryBufferRef MB);
32
33StringRef getFilenameWithoutExe(StringRef Path);
34
3235} // namespace args
3336} // 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) {
153153inline std::string toString(const Twine &S) { return S.str(); }
154154
155155// 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
158158} // namespace lld
159159
deps/lld/include/lld/Common/LLVM.h+58-42
......@@ -22,53 +22,69 @@
2222#include <utility>
2323
2424namespace llvm {
25 // ADT's.
26 class Error;
27 class StringRef;
28 class Twine;
29 class MemoryBuffer;
30 class MemoryBufferRef;
31 template<typename T> class ArrayRef;
32 template<unsigned InternalLen> class SmallString;
33 template<typename T, unsigned N> class SmallVector;
34 template<typename T> class SmallVectorImpl;
25// ADT's.
26class raw_ostream;
27class Error;
28class StringRef;
29class Twine;
30class MemoryBuffer;
31class MemoryBufferRef;
32template <typename T> class ArrayRef;
33template <unsigned InternalLen> class SmallString;
34template <typename T, unsigned N> class SmallVector;
35template <typename T> class ErrorOr;
36template <typename T> class Expected;
3537
36 template<typename T>
37 struct SaveAndRestore;
38namespace object {
39class WasmObjectFile;
40struct WasmSection;
41struct WasmSegment;
42class WasmSymbol;
43} // namespace object
3844
39 template<typename T>
40 class ErrorOr;
41
42 template<typename T>
43 class Expected;
44
45 class raw_ostream;
46 // TODO: DenseMap, ...
47}
45namespace wasm {
46struct WasmEvent;
47struct WasmEventType;
48struct WasmFunction;
49struct WasmGlobal;
50struct WasmGlobalType;
51struct WasmRelocation;
52struct WasmSignature;
53} // namespace wasm
54} // namespace llvm
4855
4956namespace lld {
50 // Casting operators.
51 using llvm::isa;
52 using llvm::cast;
53 using llvm::dyn_cast;
54 using llvm::dyn_cast_or_null;
55 using llvm::cast_or_null;
57// Casting operators.
58using llvm::cast;
59using llvm::cast_or_null;
60using llvm::dyn_cast;
61using llvm::dyn_cast_or_null;
62using llvm::isa;
5663
57 // ADT's.
58 using llvm::Error;
59 using llvm::StringRef;
60 using llvm::Twine;
61 using llvm::MemoryBuffer;
62 using llvm::MemoryBufferRef;
63 using llvm::ArrayRef;
64 using llvm::SmallString;
65 using llvm::SmallVector;
66 using llvm::SmallVectorImpl;
67 using llvm::SaveAndRestore;
68 using llvm::ErrorOr;
69 using llvm::Expected;
64// ADT's.
65using llvm::ArrayRef;
66using llvm::Error;
67using llvm::ErrorOr;
68using llvm::Expected;
69using llvm::MemoryBuffer;
70using llvm::MemoryBufferRef;
71using llvm::raw_ostream;
72using llvm::SmallString;
73using llvm::SmallVector;
74using llvm::StringRef;
75using llvm::Twine;
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;
7288} // end namespace lld.
7389
7490namespace std {
......@@ -78,6 +94,6 @@ public:
7894 return llvm::hash_value(s);
7995 }
8096};
81}
97} // namespace std
8298
8399#endif
deps/lld/include/lld/Common/Strings.h-3
......@@ -41,9 +41,6 @@ private:
4141 std::vector<llvm::GlobPattern> Patterns;
4242};
4343
44inline llvm::ArrayRef<uint8_t> toArrayRef(llvm::StringRef S) {
45 return {reinterpret_cast<const uint8_t *>(S.data()), S.size()};
46}
4744} // namespace lld
4845
4946#endif
deps/lld/include/lld/Common/TargetOptionsCommandFlags.h+1
......@@ -19,4 +19,5 @@ namespace lld {
1919llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
2020llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();
2121std::string GetCPUStr();
22std::vector<std::string> GetMAttrs();
2223}
deps/lld/include/lld/Common/Threads.h+1-1
......@@ -74,7 +74,7 @@ template <typename R, class FuncTy> void parallelForEach(R &&Range, FuncTy Fn) {
7474}
7575
7676inline void parallelForEachN(size_t Begin, size_t End,
77 std::function<void(size_t)> Fn) {
77 llvm::function_ref<void(size_t)> Fn) {
7878 if (ThreadsEnabled)
7979 for_each_n(llvm::parallel::par, Begin, End, Fn);
8080 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) {
382382 if (arch == MachOLinkingContext::arch_unknown &&
383383 !parsedArgs.getLastArg(OPT_test_file_usage)) {
384384 // If no -arch and no options at all, print usage message.
385 if (parsedArgs.size() == 0)
386 table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
387 else
385 if (parsedArgs.size() == 0) {
386 table.PrintHelp(llvm::outs(),
387 (std::string(args[0]) + " [options] file...").c_str(),
388 "LLVM Linker", false);
389 } else {
388390 error("-arch not specified and could not be inferred");
391 }
389392 return false;
390393 }
391394 }
......@@ -1143,7 +1146,7 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) {
11431146/// This is where the link is actually performed.
11441147bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
11451148 raw_ostream &Error) {
1146 errorHandler().LogName = llvm::sys::path::filename(args[0]);
1149 errorHandler().LogName = args::getFilenameWithoutExe(args[0]);
11471150 errorHandler().ErrorLimitExceededMsg =
11481151 "too many errors emitted, stopping now (use "
11491152 "'-error-limit 0' to see all errors)";
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+2
......@@ -80,6 +80,7 @@ public:
8080 switch (ref->kindValue()) {
8181 case ripRel32Got:
8282 assert(targetNowGOT && "target must be GOT");
83 LLVM_FALLTHROUGH;
8384 case ripRel32GotLoad:
8485 const_cast<Reference *>(ref)
8586 ->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);
......@@ -621,6 +622,7 @@ void ArchHandler_x86_64::applyFixupFinal(
621622 // Fall into llvm_unreachable().
622623 break;
623624 }
625 llvm_unreachable("invalid x86_64 Reference Kind");
624626}
625627
626628void 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,
262262 case llvm::MachO::MH_OBJECT:
263263 _printRemainingUndefines = false;
264264 _allowRemainingUndefines = true;
265 break;
265266 default:
266267 break;
267268 }
deps/lld/test/CMakeLists.txt+3
......@@ -53,6 +53,9 @@ add_lit_testsuite(check-lld "Running lld test suite"
5353 DEPENDS ${LLD_TEST_DEPS}
5454 )
5555
56add_custom_target(lld-test-depends DEPENDS ${LLD_TEST_DEPS})
57set_target_properties(lld-test-depends PROPERTIES FOLDER "lld tests")
58
5659add_lit_testsuites(LLD ${CMAKE_CURRENT_SOURCE_DIR}
5760 PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
5861 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:
13531353 RegRelativeSym:
13541354 Offset: 48
13551355 Type: 116
1356 Register: CVRegRSP
1356 Register: RSP
13571357 VarName: __formal
13581358 - Kind: S_PROC_ID_END
13591359 ScopeEndSym:
......@@ -1528,13 +1528,13 @@ sections:
15281528 RegRelativeSym:
15291529 Offset: 48
15301530 Type: 116
1531 Register: CVRegRSP
1531 Register: RSP
15321532 VarName: argc
15331533 - Kind: S_REGREL32
15341534 RegRelativeSym:
15351535 Offset: 56
15361536 Type: 4098
1537 Register: CVRegRSP
1537 Register: RSP
15381538 VarName: argv
15391539 - Kind: S_PROC_ID_END
15401540 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-file-statics-b.yaml+1-1
......@@ -1328,7 +1328,7 @@ sections:
13281328 RegRelativeSym:
13291329 Offset: 48
13301330 Type: 116
1331 Register: CVRegRSP
1331 Register: RSP
13321332 VarName: __formal
13331333 - Kind: S_PROC_ID_END
13341334 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-scopes-a.yaml+4-4
......@@ -53,7 +53,7 @@ sections:
5353 RegRelativeSym:
5454 Offset: 8
5555 Type: 116
56 Register: CVRegRSP
56 Register: RSP
5757 VarName: x
5858 - Kind: S_PROC_ID_END
5959 ScopeEndSym:
......@@ -93,7 +93,7 @@ sections:
9393 RegRelativeSym:
9494 Offset: 64
9595 Type: 116
96 Register: CVRegRSP
96 Register: RSP
9797 VarName: argc
9898 - Kind: S_BLOCK32
9999 BlockSym:
......@@ -104,7 +104,7 @@ sections:
104104 RegRelativeSym:
105105 Offset: 32
106106 Type: 116
107 Register: CVRegRSP
107 Register: RSP
108108 VarName: x
109109 - Kind: S_END
110110 ScopeEndSym:
......@@ -117,7 +117,7 @@ sections:
117117 RegRelativeSym:
118118 Offset: 36
119119 Type: 116
120 Register: CVRegRSP
120 Register: RSP
121121 VarName: y
122122 - Kind: S_END
123123 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-scopes-b.yaml+3-3
......@@ -53,7 +53,7 @@ sections:
5353 RegRelativeSym:
5454 Offset: 64
5555 Type: 116
56 Register: CVRegRSP
56 Register: RSP
5757 VarName: x
5858 - Kind: S_BLOCK32
5959 BlockSym:
......@@ -64,7 +64,7 @@ sections:
6464 RegRelativeSym:
6565 Offset: 32
6666 Type: 116
67 Register: CVRegRSP
67 Register: RSP
6868 VarName: y
6969 - Kind: S_END
7070 ScopeEndSym:
......@@ -77,7 +77,7 @@ sections:
7777 RegRelativeSym:
7878 Offset: 36
7979 Type: 116
80 Register: CVRegRSP
80 Register: RSP
8181 VarName: w
8282 - Kind: S_END
8383 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:
5353 RegRelativeSym:
5454 Offset: 32
5555 Type: 4102
56 Register: CVRegRSP
56 Register: RSP
5757 VarName: f
5858 - Kind: S_PROC_ID_END
5959 ScopeEndSym:
deps/lld/test/COFF/Inputs/pdb-type-server-simple-b.yaml+1-1
......@@ -53,7 +53,7 @@ sections:
5353 RegRelativeSym:
5454 Offset: 8
5555 Type: 4097
56 Register: CVRegRSP
56 Register: RSP
5757 VarName: p
5858 - Kind: S_PROC_ID_END
5959 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 @@
11// REQUIRES: arm
22// 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.obj
4// RUN: not lld-link -entry:_start -subsystem:console %t.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
3// RUN: not lld-link -entry:_start -subsystem:console %t.obj -out:%t.exe 2>&1 | FileCheck %s
54 .syntax unified
65 .globl _start
76_start:
87 bne too_far20
8 .space 0x100000
9 .section .text$a, "xr"
10too_far20:
11 bx lr
912
10// CHECK: relocation out of range
13// 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 @@
3434# BEFORE: 64: e0 03 1f 2a mov w0, wzr
3535# BEFORE: 68: fe 07 41 f8 ldr x30, [sp], #16
3636# BEFORE: 6c: c0 03 5f d6 ret
37# BEFORE: 70: 08 00 00 00 <unknown>
38# BEFORE: 74: 00 00 00 00 <unknown>
39# BEFORE: 78: 01 00 00 00 <unknown>
40# BEFORE: 7c: 01 00 00 00 <unknown>
37# BEFORE: 70: 08 00 00 00 udf #8
38# BEFORE: 74: 00 00 00 00 udf #0
39# BEFORE: 78: 01 00 00 00 udf #1
40# BEFORE: 7c: 01 00 00 00 udf #1
4141# BEFORE: 80: 00 00 00 91 add x0, x0, #0
4242# BEFORE: 84: 00 00 40 91 add x0, x0, #0, lsl #12
4343# 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
4545# BEFORE: 90: 20 1a 09 30 adr x0, #74565
4646# BEFORE: 94: 01 00 00 54 b.ne #0
4747# BEFORE: 98: 00 00 00 36 tbz w0, #0, #0
......@@ -76,13 +76,13 @@
7676# AFTER: 140001068: fe 07 41 f8 ldr x30, [sp], #16
7777# AFTER: 14000106c: c0 03 5f d6 ret
7878# AFTER: 140001070: 10 20 00 40 <unknown>
79# AFTER: 140001074: 01 00 00 00 <unknown>
80# AFTER: 140001078: 09 20 00 00 <unknown>
81# AFTER: 14000107c: 09 00 00 00 <unknown>
79# AFTER: 140001074: 01 00 00 00 udf #1
80# AFTER: 140001078: 09 20 00 00 udf #8201
81# AFTER: 14000107c: 09 00 00 00 udf #9
8282# AFTER: 140001080: 00 20 0e 91 add x0, x0, #904
8383# AFTER: 140001084: 00 04 40 91 add x0, x0, #1, lsl #12
8484# 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
8686# AFTER: 140001090: e0 95 09 30 adr x0, #78525
8787# AFTER: 140001094: 41 00 00 54 b.ne #8
8888# 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 @@
1111# CHECK: Number: 2
1212# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)
1313# 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).
1516# Make sure that no other .xdata sections get included, which would
1617# increase the size here.
17# CHECK-NEXT: VirtualSize: 0x4
18# CHECK-NEXT: VirtualSize: 0x24
1819
1920 .text
2021 .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 @@
4747# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \
4848# RUN: --check-prefix=BASEREL-HEADER
4949#
50# RN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
51# RN: llvm-readobj -file-headers %t.exe | FileCheck %s \
52# RN: --check-prefix=NOBASEREL-HEADER
50# RUN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
51# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s \
52# RUN: --check-prefix=NOBASEREL-HEADER
5353#
5454# BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
5555#
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 @@
1414
1515# SECTIONS: Name: .data (2E 64 61 74 61 00 00 00)
1616# SECTIONS-NEXT: VirtualSize: 0x8
17# SECTIONS-NEXT: VirtualAddress: 0x2000
17# SECTIONS-NEXT: VirtualAddress: 0x3000
1818# 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 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s
3# RUN: lld-link -entry:main %t.obj -out:%t.exe
3# RUN: lld-link -lldmingw -entry:main %t.obj -out:%t.exe
44# RUN: llvm-objdump -s %t.exe | FileCheck %s
55
66.globl main
77main:
88 nop
99
10# Check that these symbols point at the right spots.
11.data
12 .quad __CTOR_LIST__
13 .quad __DTOR_LIST__
14
1015.section .ctors.00005, "w"
1116 .quad 2
1217.section .ctors, "w"
......@@ -15,16 +20,26 @@ main:
1520 .quad 3
1621
1722.section .dtors, "w"
18 .quad 1
23 .quad 4
1924.section .dtors.00100, "w"
20 .quad 3
25 .quad 6
2126.section .dtors.00005, "w"
22 .quad 2
27 .quad 5
28
29# Also test that the .CRT section is merged into .rdata
2330
24# CHECK: Contents of section .ctors:
25# CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000
26# CHECK-NEXT: 140002010 03000000 00000000
31.section .CRT$XCA, "dw"
32 .quad 7
33 .quad 8
2734
28# CHECK: Contents of section .dtors:
29# CHECK-NEXT: 140003000 01000000 00000000 02000000 00000000
30# CHECK-NEXT: 140003010 03000000 00000000
35# CHECK: Contents of section .rdata:
36# CHECK-NEXT: 140002000 07000000 00000000 08000000 00000000
37# 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 @@
88# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s -check-prefix HEADERS
99# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG
1010
11# SECTIONS: Number: 2
11# SECTIONS: Number: 3
1212# SECTIONS-NEXT: Name: .buildid (2E 62 75 69 6C 64 69 64)
1313# SECTIONS-NEXT: VirtualSize: 0x35
14# SECTIONS-NEXT: VirtualAddress: 0x2000
15# SECTIONS: Number: 3
14# SECTIONS-NEXT: VirtualAddress: 0x3000
15# SECTIONS: Number: 4
1616# SECTIONS-NEXT: Name: .data (2E 64 61 74 61 00 00 00)
1717# SECTIONS-NEXT: VirtualSize: 0x8
18# SECTIONS-NEXT: VirtualAddress: 0x3000
18# SECTIONS-NEXT: VirtualAddress: 0x4000
1919
2020# RELOCS: BaseReloc [
2121# RELOCS-NEXT: Entry {
2222# RELOCS-NEXT: Type: DIR64
23# RELOCS-NEXT: Address: 0x3000
23# RELOCS-NEXT: Address: 0x4000
2424# RELOCS-NEXT: }
2525# RELOCS-NEXT: Entry {
2626# RELOCS-NEXT: Type: ABSOLUTE
27# RELOCS-NEXT: Address: 0x3000
27# RELOCS-NEXT: Address: 0x4000
2828# RELOCS-NEXT: }
2929# RELOCS-NEXT: ]
3030
31# HEADERS: DebugRVA: 0x2000
31# HEADERS: DebugRVA: 0x3000
3232# HEADERS: DebugSize: 0x1C
3333
3434# DEBUG: DebugDirectory [
3535# DEBUG: DebugEntry {
3636# DEBUG: Type: CodeView (0x2)
3737# DEBUG: SizeOfData: 0x19
38# DEBUG: AddressOfRawData: 0x201C
39# DEBUG: PointerToRawData: 0x61C
38# DEBUG: AddressOfRawData: 0x301C
39# DEBUG: PointerToRawData: 0x81C
4040
4141 .text
4242 .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 @@
11# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
22# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
33# 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
57# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
68# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
79# 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
913# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
1014# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
1115# 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
1319# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
1420# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
1521# 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
1725# MAIN: error: <root>: undefined symbol: mainCRTStartup
1826# WMAIN: error: <root>: undefined symbol: wmainCRTStartup
deps/lld/test/COFF/entry-inference4.test+16-4
......@@ -14,10 +14,22 @@
1414# RUN: not lld-link /subsystem:console /out:%t.exe %t.obj > %t.log 2>&1
1515# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
1616
17# MAIN: error: <root>: undefined symbol: mainCRTStartup
18# WMAIN: error: <root>: undefined symbol: wmainCRTStartup
19# WINMAIN: error: <root>: undefined symbol: WinMainCRTStartup
20# WWINMAIN: error: <root>: undefined symbol: wWinMainCRTStartup
17# RUN: sed 's/ENTRY1/wmain/;s/ENTRY2/main/' %s | yaml2obj > %t.obj
18# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
19# RUN: FileCheck -check-prefix=MAINWMAIN %s < %t.log
20
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
2234--- !COFF
2335header:
deps/lld/test/COFF/export-all.s+21-6
......@@ -3,14 +3,13 @@
33# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
44
55# 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 %s
6# RUN: llvm-readobj -coff-exports %t.dll | grep Name: | FileCheck %s
77# RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s
88
9# CHECK-NOT: Name: DllMainCRTStartup
10# CHECK-NOT: Name: _imp__unexported
11# CHECK: Name: dataSym
12# CHECK: Name: foobar
13# CHECK-NOT: Name: unexported
9# CHECK: Name:
10# CHECK-NEXT: Name: dataSym
11# CHECK-NEXT: Name: foobar
12# CHECK-EMPTY:
1413
1514# IMPLIB: Symbol: __imp__dataSym
1615# IMPLIB-NOT: Symbol: _dataSym
......@@ -22,6 +21,7 @@
2221.global _dataSym
2322.global _unexported
2423.global __imp__unexported
24.global .refptr._foobar
2525.text
2626_DllMainCRTStartup@12:
2727 ret
......@@ -34,6 +34,8 @@ _dataSym:
3434 .int 4
3535__imp__unexported:
3636 .int _unexported
37.refptr._foobar:
38 .int _foobar
3739
3840# Test specifying -export-all-symbols, on an object file that contains
3941# dllexport directive for some of the symbols.
......@@ -63,6 +65,7 @@ __imp__unexported:
6365# RUN: mkdir -p %T/libs
6466# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s
6567# 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
6669# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o
6770# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s
6871# 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:
7477# CHECK-EXCLUDE-NEXT: foobar @1
7578# 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
7792# Test that we handle import libraries together with -opt:noref.
7893
7994# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
deps/lld/test/COFF/export.test+9
......@@ -97,3 +97,12 @@ FORWARDER: Ordinal RVA Name
9797FORWARDER: 0 0
9898FORWARDER: 1 0x1010 exportfn
9999FORWARDER: 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)
3434IMPORT-NEXT: Symbol: (50)
3535IMPORT-NEXT: Symbol: MessageBoxA (1)
3636IMPORT-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 @@
11# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
22# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
33# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj
4# 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 @@
11; REQUIRES: x86
2; NetBSD: noatime mounts currently inhibit 'touch' from updating atime
3; UNSUPPORTED: system-netbsd
24
35; RUN: opt -module-hash -module-summary %s -o %t.o
46; 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 @@
22; RUN: llvm-as -o %t.obj %s
33; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s
44; 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
56; RUN: llvm-ar cru %t.lib %T/lto-chkstk-chkstk.obj
67; 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
44RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb
55RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb
66RUN: 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 %s
8RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s
9RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s
7RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.nohash.pdb | FileCheck %s
8RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.hash.pdb | FileCheck %s
9RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.mixed.pdb | FileCheck %s
1010
1111; These object files were generated via the following inputs and commands:
1212; ----------------------------------------------
deps/lld/test/COFF/pdb-globals.test+5-1
......@@ -15,6 +15,8 @@ RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
1515CHECK-LABEL: Global Symbols
1616CHECK-NEXT: ============================================================
1717CHECK-NEXT: Records
18CHECK-NEXT: 340 | S_UDT [size = 20] `HelloPoint`
19CHECK-NEXT: original type = 0x1007
1820CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc`
1921CHECK-NEXT: module = 1, sum name = 0, offset = 292
2022CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc`
......@@ -25,9 +27,11 @@ CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall`
2527CHECK-NEXT: type = 0x0403 (void*), addr = 0003:0004
2628CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar`
2729CHECK-NEXT: type = 0x100B (const int*), addr = 0003:0000
30CHECK-NEXT: 312 | S_UDT [size = 28] `HelloPointTypedef`
31CHECK-NEXT: original type = 0x1005
2832CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar`
2933CHECK-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`
3135CHECK-NEXT: module = 1, sum name = 0, offset = 376
3236
3337CHECK-LABEL: Symbols
deps/lld/test/COFF/pdb-heapsite.yaml+1-1
......@@ -69,7 +69,7 @@ sections:
6969 RegRelativeSym:
7070 Offset: 8
7171 Type: 35
72 Register: CVRegRSP
72 Register: RSP
7373 VarName: __formal
7474 - Kind: S_PROC_ID_END
7575 ScopeEndSym:
deps/lld/test/COFF/pdb-linker-module.test+3-3
......@@ -1,11 +1,11 @@
11RUN: echo "/nodefaultlib" > %t.rsp
2RUN: lld-link /debug /pdb:%t.pdb @%t.rsp /entry:main %S/Inputs/pdb-diff.obj
2RUN: lld-link /debug /pdb:%t.pdb @%t.rsp /entry:"1 "'"'hello'"'" 2" /manifestuac:"level='asInvoker' uiAccess='false'" %S/Inputs/pdb-diff.obj /force
33RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s
44RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s
55
66MODS: Mod 0001 | `* Linker *`
77MODS-NEXT: Obj: ``:
8MODS-NEXT: debug stream: 12, # files: 0, has ec info: false
8MODS-NEXT: debug stream: 13, # files: 0, has ec info: false
99MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 ``
1010
1111SYMS: Mod 0001 | `* Linker *`
......@@ -22,4 +22,4 @@ SYMS-NEXT: - {{.*}}lld-link
2222SYMS-NEXT: - pdb
2323SYMS-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb
2424SYMS-NEXT: - cmd
25SYMS-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj
25SYMS-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 @@
66# RUN: lld-link /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
77# 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
914; If /DEBUG and /pdb are specified, it uses the specified name.
1015# RUN: lld-link /DEBUG /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
1116# 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
1414CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]
1515CHECK-NEXT: size = 40, padding size = 0, offset to padding = 0
1616CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000
17CHECK-NEXT: local fp reg = NONE, param fp reg = NONE
1718CHECK-NEXT: flags = has async eh | opt speed
1819CHECK-NEXT: 168 | S_END [size = 4]
1920CHECK-LABEL: Mod 0001 |
......@@ -23,6 +24,7 @@ CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end
2324CHECK-NEXT: 136 | S_FRAMEPROC [size = 32]
2425CHECK-NEXT: size = 0, padding size = 0, offset to padding = 0
2526CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000
27CHECK-NEXT: local fp reg = NONE, param fp reg = NONE
2628CHECK-NEXT: flags = has async eh | opt speed
2729CHECK-NEXT: 168 | S_END [size = 4]
2830CHECK-LABEL: Mod 0002 |
deps/lld/test/COFF/pdb-relative-source-lines.test+79-19
......@@ -17,29 +17,89 @@ void bar(void) {
1717
1818$ 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.obj
21RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t.pdb_lines_2_relative.obj
22RUN: rm -f %t.exe %t.pdb
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.obj
24RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
25
26CHECK-LABEL: - Module: {{.*}}pdb_lines_1_relative.obj
27CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1_relative.obj
20/pdbsourcepath: only sets the directory that relative paths are considered
21relative to, so this test needs to pass relative paths to lld-link for:
221. The input obj files
232. The /pdb: switch
243. The lld-link invocation itself
25To achieve this, put all inputs of the lld-link invocation (including lld-link
26itself) in a temp directory that's cwd and then make sure to only use relative
27arguments 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'
2842CHECK: SourceFiles:
29CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'
30CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}foo.h'
43CHECK-NEXT: - 'c:\src\pdb_lines_1.c'
44CHECK-NEXT: - 'c:\src\foo.h'
3145CHECK: Subsections:
32CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'
33CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h'
46CHECK: - FileName: 'c:\src\pdb_lines_1.c'
47CHECK: - FileName: 'c:\src\foo.h'
3448CHECK: - !FileChecksums
35CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'
36CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h'
49CHECK: - FileName: 'c:\src\pdb_lines_1.c'
50CHECK: - FileName: 'c:\src\foo.h'
3751
38CHECK-LABEL: - Module: {{.*}}pdb_lines_2_relative.obj
39CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2_relative.obj
52CHECK-LABEL: - Module: 'c:\src\pdb_lines_2_relative.obj'
53CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_2_relative.obj'
4054CHECK: SourceFiles:
41CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'
55CHECK-NEXT: - 'c:\src\pdb_lines_2.c'
4256CHECK: Subsections:
43CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'
57CHECK: - FileName: 'c:\src\pdb_lines_2.c'
4458CHECK: - !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 @@
1414RAW: Modules
1515RAW-NEXT: ============================================================
1616RAW-NEXT: Mod 0000 | `foo.obj`:
17RAW-NEXT: Obj: `{{.*}}1\foo.lib`:
17RAW-NEXT: Obj: `{{.*}}1{{[\\/]}}foo.lib`:
1818RAW-NEXT: debug stream: 11, # files: 1, has ec info: false
1919RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
2020RAW-NEXT: Mod 0001 | `foo.obj`:
21RAW-NEXT: Obj: `{{.*}}2\foo.lib`:
21RAW-NEXT: Obj: `{{.*}}2{{[\\/]}}foo.lib`:
2222RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
2323RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
deps/lld/test/COFF/pdb-symbol-types.yaml+6-2
......@@ -17,9 +17,13 @@
1717# CHECK-NEXT: ============================================================
1818# CHECK-NEXT: Records
1919# CHECK-NEXT: 48 | S_PROCREF [size = 20] `main`
20# CHECK-NEXT: module = 1, sum name = 0, offset = 116
20# 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
2125# CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo`
22# CHECK-NEXT: type = 0x1004 (Foo), addr = 0003:0000
26# CHECK-NEXT: type = 0x1004 (Foo), addr = 0003:0000
2327
2428# CHECK: Symbols
2529# CHECK: ============================================================
deps/lld/test/COFF/pdb-thunk.yaml+6-6
......@@ -84,7 +84,7 @@ sections:
8484 RegRelativeSym:
8585 Offset: 8
8686 Type: 4097
87 Register: CVRegRSP
87 Register: RSP
8888 VarName: this
8989 - Kind: S_PROC_ID_END
9090 ScopeEndSym:
......@@ -124,7 +124,7 @@ sections:
124124 RegRelativeSym:
125125 Offset: 8
126126 Type: 4121
127 Register: CVRegRSP
127 Register: RSP
128128 VarName: this
129129 - Kind: S_PROC_ID_END
130130 ScopeEndSym:
......@@ -164,7 +164,7 @@ sections:
164164 RegRelativeSym:
165165 Offset: 48
166166 Type: 4143
167 Register: CVRegRSP
167 Register: RSP
168168 VarName: this
169169 - Kind: S_PROC_ID_END
170170 ScopeEndSym:
......@@ -208,7 +208,7 @@ sections:
208208 RegRelativeSym:
209209 Offset: 8
210210 Type: 4143
211 Register: CVRegRSP
211 Register: RSP
212212 VarName: this
213213 - Kind: S_PROC_ID_END
214214 ScopeEndSym:
......@@ -2176,7 +2176,7 @@ sections:
21762176 RegRelativeSym:
21772177 Offset: 8
21782178 Type: 4097
2179 Register: CVRegRSP
2179 Register: RSP
21802180 VarName: this
21812181 - Kind: S_PROC_ID_END
21822182 ScopeEndSym:
......@@ -2222,7 +2222,7 @@ sections:
22222222 RegRelativeSym:
22232223 Offset: 8
22242224 Type: 4121
2225 Register: CVRegRSP
2225 Register: RSP
22262226 VarName: this
22272227 - Kind: S_PROC_ID_END
22282228 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 @@
11# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
22# 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.obj
5# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
5# RUN: yaml2obj %s -o %t1.obj
6# 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
924--- !COFF
1025header:
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`
6262CHECK-LABEL: Global Symbols
6363CHECK: ============================================================
6464CHECK-NEXT: Records
65CHECK-NEXT: 36 | S_PROCREF [size = 20] `main`
66CHECK-NEXT: module = 1, sum name = 0, offset = 104
67CHECK-NEXT: 56 | S_PROCREF [size = 16] `g`
68CHECK-NEXT: module = 2, sum name = 0, offset = 104
65CHECK-NEXT: 36 | S_PROCREF [size = 20] `main`
66CHECK-NEXT: module = 1, sum name = 0, offset = 104
67CHECK-NEXT: 68 | S_PROCREF [size = 16] `g`
68CHECK-NEXT: module = 2, sum name = 0, offset = 104
69CHECK-NEXT: 56 | S_UDT [size = 12] `Foo`
70CHECK-NEXT: original type = 0x1006
6971
7072CHECK-LABEL: Symbols
7173CHECK: ============================================================
......@@ -89,7 +91,7 @@ CHECK: size = 0, padding size = 0, offset to padding = 0
8991CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
9092CHECK: flags = has async eh | opt speed
9193CHECK: 180 | S_REGREL32 [size = 16] `p`
92CHECK: type = [[FOO_PTR]] (Foo*), register = CVRegRSP, offset = 8
94CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8
9395CHECK: 196 | S_END [size = 4]
9496CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
9597CHECK-LABEL: Mod 0002 | `* Linker *`:
deps/lld/test/COFF/pdb.test-19
......@@ -193,25 +193,6 @@ RAW-NEXT: flags = function, addr = 0001:0000
193193RAW-NEXT: 0 | S_PUB32 [size = 20] `foo`
194194RAW-NEXT: flags = function, addr = 0001:0016
195195RAW-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: )
215196RAW-NEXT: Hash Entries
216197RAW-NEXT: off = 21, refcnt = 1
217198RAW-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 @@
1010# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:noref 2>&1 | FileCheck %s
1111
1212# CHECK: error: relocation against symbol in discarded section: assoc_global
13# CHECK: >>> referenced by {{.*}}reloc-discarded{{.*}}.obj:(main)
1314
1415 .section .bss,"bw",discard,main_global
1516 .globl main_global
deps/lld/test/COFF/rsds.test+120-6
......@@ -1,9 +1,9 @@
11# RUN: yaml2obj %s > %t.obj
22
33# RUN: rm -f %t.dll %t.pdb
4# RUN: lld-link /debug /pdbaltpath:test1.pdb /dll /out:%t.dll /entry:DllMain %t.obj
4# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
55# 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.obj
6# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
77# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt
88# RUN: cat %t.1.txt %t.2.txt | FileCheck %s
99
......@@ -12,7 +12,19 @@
1212# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
1313# RUN: lld-link /debug /pdb:%t2.pdb /dll /out:%t.dll /entry:DllMain %t.obj
1414# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
15# RUN: cat %t.3.txt %t.4.txt | FileCheck %s
15# 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
1729# CHECK: File: [[FILE:.*]].dll
1830# CHECK: DebugDirectory [
......@@ -29,7 +41,7 @@
2941# CHECK: PDBSignature: 0x53445352
3042# CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
3143# CHECK: PDBAge: 1
32# CHECK: PDBFileName: {{.*}}1.pdb
44# CHECK: PDBFileName: {{.*}}.pdb
3345# CHECK: }
3446# CHECK: }
3547# CHECK: ]
......@@ -47,12 +59,114 @@
4759# CHECK: PDBInfo {
4860# CHECK: PDBSignature: 0x53445352
4961# CHECK: PDBGUID: [[GUID]]
50# CHECK: PDBAge: 2
51# CHECK: PDBFileName: {{.*}}2.pdb
62# CHECK: PDBAge: 1
63# CHECK: PDBFileName: {{.*}}.pdb
5264# CHECK: }
5365# CHECK: }
5466# 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: ]
56170--- !COFF
57171header:
58172 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 @@
66; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll
77; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj
88; 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 \
10; RUN: -subsystem:console %T/thinlto-archives/main.obj \
9; RUN: lld-link -out:%T/thinlto-archives/main.exe -entry:main \
10; RUN: -lldsavetemps -subsystem:console %T/thinlto-archives/main.obj \
1111; 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
1321target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
1422target triple = "x86_64-pc-windows-msvc"
deps/lld/test/COFF/undefined-symbol-cv.s+5-5
......@@ -2,19 +2,19 @@
22# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
33# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
44
5# CHECK: error: undefined symbol: ?foo@@YAHXZ
5# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
66# CHECK-NEXT: >>> referenced by file1.cpp:1
77# CHECK-NEXT: >>> {{.*}}.obj:(main)
88# CHECK-NEXT: >>> referenced by file1.cpp:2
99# CHECK-NEXT: >>> {{.*}}.obj:(main)
10
11# CHECK: error: undefined symbol: ?bar@@YAHXZ
10# CHECK-EMPTY:
11# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
1212# CHECK-NEXT: >>> referenced by file2.cpp:3
1313# CHECK-NEXT: >>> {{.*}}.obj:(main)
1414# CHECK-NEXT: >>> referenced by file1.cpp:4
1515# CHECK-NEXT: >>> {{.*}}.obj:(f1)
16
17# CHECK: error: undefined symbol: ?baz@@YAHXZ
16# CHECK-EMPTY:
17# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ)
1818# CHECK-NEXT: >>> referenced by file1.cpp:5
1919# CHECK-NEXT: >>> {{.*}}.obj:(f2)
2020
deps/lld/test/COFF/undefined-symbol.s+6-6
......@@ -2,15 +2,15 @@
22# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
33# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
44
5# CHECK: error: undefined symbol: ?foo@@YAHXZ
5# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
66# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
77# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
8
9# CHECK: error: undefined symbol: ?bar@@YAHXZ
8# CHECK-EMPTY:
9# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
1010# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
1111# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
12
13# CHECK: error: undefined symbol: ?baz@@YAHXZ
12# CHECK-EMPTY:
13# CHECK-NEXT: error: undefined symbol: "__declspec(dllimport) int __cdecl baz(void)" (__imp_?baz@@YAHXZ)
1414# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)
1515
1616 .section .text,"xr",one_only,main
......@@ -27,4 +27,4 @@ f1:
2727 .section .text,"xr",one_only,f2
2828.globl f2
2929f2:
30 call "?baz@@YAHXZ"
30 callq *"__imp_?baz@@YAHXZ"(%rip)
deps/lld/test/COFF/wholearchive.s+1
......@@ -1,6 +1,7 @@
11# REQUIRES: x86
22
33# RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj
4# RUN: rm -f %t.archive.lib
45# RUN: llvm-ar rcs %t.archive.lib %t.archive.obj
56# 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:
1414// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1515
1616// CHECK: Contents of section .data:
17// 11000: S = 0x100, A = 0xfeff
18// S + A = 0xffff
19// 11002: S = 0x100, A = -0x8100
20// S + A = 0x8000
21// CHECK-NEXT: 20000 ffff0080
17// 210000: S = 0x100, A = 0xfeff
18// S + A = 0xffff
19// 210002: S = 0x100, A = -0x8100
20// S + A = 0x8000
21// CHECK-NEXT: 210000 ffff0080
2222
23// RUN: not ld.lld %t.o %t255.o -o %t2
24// | FileCheck %s --check-prefix=OVERFLOW
25// RUN: not ld.lld %t.o %t257.o -o %t2
26// | FileCheck %s --check-prefix=OVERFLOW
27// OVERFLOW: Relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]
23// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 32767]
25
26// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
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:
1414// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1515
1616// CHECK: Contents of section .data:
17// 20000: S = 0x100, A = 0xfffffeff
18// S + A = 0xffffffff
19// 20004: S = 0x100, A = -0x80000100
20// S + A = 0x80000000
21// CHECK-NEXT: 20000 ffffffff 00000080
17// 210000: S = 0x100, A = 0xfffffeff
18// S + A = 0xffffffff
19// 210004: S = 0x100, A = -0x80000100
20// S + A = 0x80000000
21// CHECK-NEXT: 210000 ffffffff 00000080
2222
23// RUN: not ld.lld %t.o %t255.o -o %t2
24// | FileCheck %s --check-prefix=OVERFLOW
25// RUN: not ld.lld %t.o %t257.o -o %t2
26// | FileCheck %s --check-prefix=OVERFLOW
27// OVERFLOW: Relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]
23// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 2147483647]
25
26// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
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:
1111
1212// CHECK: Disassembly of section .text:
1313// CHECK-NEXT: _start:
14// CHECK-NEXT: 20000: 02 00 00 94 bl #8
14// CHECK-NEXT: 210000: 02 00 00 94 bl #8
1515// CHECK: __AArch64AbsLongThunk_big:
16// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 2000c: 00 02 1f d6 br x16
16// CHECK-NEXT: 210008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 21000c: 00 02 1f d6 br x16
1818// CHECK: $d:
19// CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000
20// CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010
19// CHECK-NEXT: 210010: 00 00 00 00 .word 0x00000000
20// 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 @@
1212# 0x1102c - 16 = 0x1101c
1313# CHECK: Disassembly of section .text:
1414# CHECK-NEXT: _foo:
15# CHECK-NEXT: 20000: {{.*}} nop
16# CHECK-NEXT: 20004: {{.*}} nop
17# CHECK-NEXT: 20008: {{.*}} nop
18# CHECK-NEXT: 2000c: {{.*}} nop
15# CHECK-NEXT: 210000: {{.*}} nop
16# CHECK-NEXT: 210004: {{.*}} nop
17# CHECK-NEXT: 210008: {{.*}} nop
18# CHECK-NEXT: 21000c: {{.*}} nop
1919# CHECK: _bar:
20# CHECK-NEXT: 20010: {{.*}} nop
21# CHECK-NEXT: 20014: {{.*}} nop
22# CHECK-NEXT: 20018: {{.*}} nop
20# CHECK-NEXT: 210010: {{.*}} nop
21# CHECK-NEXT: 210014: {{.*}} nop
22# CHECK-NEXT: 210018: {{.*}} nop
2323# CHECK: _dah:
24# CHECK-NEXT: 2001c: {{.*}} nop
25# CHECK-NEXT: 20020: {{.*}} nop
24# CHECK-NEXT: 21001c: {{.*}} nop
25# CHECK-NEXT: 210020: {{.*}} nop
2626# CHECK: _start:
27# CHECK-NEXT: 20024: {{.*}} b.eq #-36
28# CHECK-NEXT: 20028: {{.*}} b.eq #-24
29# CHECK-NEXT: 2002c: {{.*}} b.eq #-16
27# CHECK-NEXT: 210024: {{.*}} b.eq #-36
28# CHECK-NEXT: 210028: {{.*}} b.eq #-24
29# CHECK-NEXT: 21002c: {{.*}} b.eq #-16
3030
3131#DSOREL: Section {
3232#DSOREL: Index:
......@@ -79,14 +79,20 @@
7979#DSO-NEXT: 10044: {{.*}} nop
8080#DSO-NEXT: 10048: {{.*}} nop
8181#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-EMPTY:
83#DSO-NEXT: _foo@plt:
8284#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
8385#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
8486#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
8587#DSO-NEXT: 1005c: {{.*}} br x17
88#DSO-EMPTY:
89#DSO-NEXT: _bar@plt:
8690#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
8791#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
8892#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
8993#DSO-NEXT: 1006c: {{.*}} br x17
94#DSO-EMPTY:
95#DSO-NEXT: _dah@plt:
9096#DSO-NEXT: 10070: {{.*}} adrp x16, #65536
9197#DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40]
9298#DSO-NEXT: 10078: {{.*}} add x16, x16, #40
deps/lld/test/ELF/aarch64-copy.s+16-16
......@@ -22,7 +22,7 @@ _start:
2222// CHECK-NEXT: SHF_ALLOC
2323// CHECK-NEXT: SHF_WRITE
2424// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x40000
25// CHECK-NEXT: Address: 0x230000
2626// CHECK-NEXT: Offset:
2727// CHECK-NEXT: Size: 24
2828// CHECK-NEXT: Link:
......@@ -32,19 +32,19 @@ _start:
3232// CHECK: Relocations [
3333// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
3434// CHECK-NEXT: Relocation {
35// CHECK-NEXT: Offset: 0x40000
35// CHECK-NEXT: Offset: 0x230000
3636// CHECK-NEXT: Type: R_AARCH64_COPY
3737// CHECK-NEXT: Symbol: x
3838// CHECK-NEXT: Addend: 0x0
3939// CHECK-NEXT: }
4040// CHECK-NEXT: Relocation {
41// CHECK-NEXT: Offset: 0x40010
41// CHECK-NEXT: Offset: 0x230010
4242// CHECK-NEXT: Type: R_AARCH64_COPY
4343// CHECK-NEXT: Symbol: y
4444// CHECK-NEXT: Addend: 0x0
4545// CHECK-NEXT: }
4646// CHECK-NEXT: Relocation {
47// CHECK-NEXT: Offset: 0x40014
47// CHECK-NEXT: Offset: 0x230014
4848// CHECK-NEXT: Type: R_AARCH64_COPY
4949// CHECK-NEXT: Symbol: z
5050// CHECK-NEXT: Addend: 0x0
......@@ -54,21 +54,21 @@ _start:
5454
5555// CHECK: Symbols [
5656// CHECK: Name: x
57// CHECK-NEXT: Value: 0x40000
57// CHECK-NEXT: Value: 0x230000
5858// CHECK-NEXT: Size: 4
5959// CHECK-NEXT: Binding: Global
6060// CHECK-NEXT: Type: Object
6161// CHECK-NEXT: Other:
6262// CHECK-NEXT: Section: .bss
6363// CHECK: Name: y
64// CHECK-NEXT: Value: 0x40010
64// CHECK-NEXT: Value: 0x230010
6565// CHECK-NEXT: Size: 4
6666// CHECK-NEXT: Binding: Global
6767// CHECK-NEXT: Type: Object
6868// CHECK-NEXT: Other:
6969// CHECK-NEXT: Section: .bss
7070// CHECK: Name: z
71// CHECK-NEXT: Value: 0x40014
71// CHECK-NEXT: Value: 0x230014
7272// CHECK-NEXT: Size: 4
7373// CHECK-NEXT: Binding: Global
7474// CHECK-NEXT: Type: Object
......@@ -78,16 +78,16 @@ _start:
7878
7979// CODE: Disassembly of section .text:
8080// CODE-NEXT: _start:
81// S(x) = 0x40000, A = 0, P = 0x20000
81// S(x) = 0x230000, A = 0, P = 0x210000
8282// S + A - P = 0x20000 = 131072
83// CODE-NEXT: 20000: {{.*}} adr x1, #131072
84// S(y) = 0x40010, A = 0, P = 0x20004
85// Page(S + A) - Page(P) = 0x40000 - 0x20000 = 0x20000 = 131072
86// CODE-NEXT: 20004: {{.*}} adrp x2, #131072
87// S(y) = 0x40010, A = 0
83// CODE-NEXT: 210000: {{.*}} adr x1, #131072
84// S(y) = 0x230010, A = 0, P = 0x210004
85// Page(S + A) - Page(P) = 0x230000 - 0x210000 = 0x20000 = 131072
86// CODE-NEXT: 210004: {{.*}} adrp x2, #131072
87// S(y) = 0x230010, A = 0
8888// (S + A) & 0xFFF = 0x10 = 16
89// CODE-NEXT: 20008: {{.*}} add x2, x2, #16
89// CODE-NEXT: 210008: {{.*}} add x2, x2, #16
9090
9191// RODATA: Contents of section .rodata:
92// S(z) = 0x40014
93// RODATA-NEXT: 102e0 14000400
92// S(z) = 0x230014
93// RODATA-NEXT: 2002e0 14002300
deps/lld/test/ELF/aarch64-copy2.s+1-1
......@@ -19,7 +19,7 @@ _start:
1919// CHECK-NEXT: Section: Undefined
2020
2121// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x20030
22// CHECK-NEXT: Value: 0x210030
2323// CHECK-NEXT: Size: 0
2424// CHECK-NEXT: Binding: Global
2525// 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 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// 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
66.globl entry
77.text
88 .quad 0
deps/lld/test/ELF/aarch64-cortex-a53-843419-large.s+37-37
......@@ -1,23 +1,23 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
33// 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 %s
5// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=135168 -stop-address=135172 | 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 %s
7// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=67256312 -stop-address=67256328 | 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 %s
9// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134352908 -stop-address=134352912 | 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 %s
4// 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=2166784 -stop-address=2166788 | FileCheck --check-prefix=CHECK2 %s
6// 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=69287928 -stop-address=69287944 | FileCheck --check-prefix=CHECK4 %s
8// 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=136384524 -stop-address=136384528 | FileCheck --check-prefix=CHECK6 %s
10// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=136388604 -stop-address=136388628 | FileCheck --check-prefix=CHECK7 %s
1111// Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding
1212// the maximum branch range. Both range extension thunks and patches are
13// required.
14
13// required.
14
1515// CHECK1: __AArch64AbsLongThunk_need_thunk_after_patch:
16// CHECK1-NEXT: 20000: 50 00 00 58 ldr x16, #8
17// CHECK1-NEXT: 20004: 00 02 1f d6 br x16
18// CHECK1: $d:
19// CHECK1-NEXT: 20008: 0c 10 02 08 .word 0x0802100c
20
16// CHECK1-NEXT: 210000: 50 00 00 58 ldr x16, #8
17// CHECK1-NEXT: 210004: 00 02 1f d6 br x16
18// CHECK1: $d:
19// CHECK1-NEXT: 210008: 0c 10 21 08 .word 0x0821100c
20
2121 .section .text.01, "ax", %progbits
2222 .balign 4096
2323 .globl _start
......@@ -29,7 +29,7 @@ _start:
2929 .space 4096 - 12
3030
3131// CHECK2: _start:
32// CHECK2-NEXT: 21000: 00 fc ff 97 bl #-4096
32// CHECK2-NEXT: 211000: 00 fc ff 97 bl #-4096
3333
3434 // Expect patch on pass 1
3535 .section .text.03, "ax", %progbits
......@@ -42,10 +42,10 @@ t3_ff8_ldr:
4242 ret
4343
4444// CHECK3: t3_ff8_ldr:
45// CHECK3-NEXT: 21ff8: 60 00 04 f0 adrp x0, #134279168
46// CHECK3-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1]
47// CHECK3-NEXT: 22000: 02 08 80 15 b #100671496
48// CHECK3-NEXT: 22004: c0 03 5f d6 ret
45// CHECK3-NEXT: 211ff8: 60 00 04 f0 adrp x0, #134279168
46// CHECK3-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
47// CHECK3-NEXT: 212000: 02 08 80 15 b #100671496
48// CHECK3-NEXT: 212004: c0 03 5f d6 ret
4949
5050 .section .text.04, "ax", %progbits
5151 .space 64 * 1024 * 1024
......@@ -63,20 +63,20 @@ t3_ff8_str:
6363 ret
6464
6565// CHECK4: t3_ff8_str:
66// CHECK4-NEXT: 4023ff8: 60 00 02 b0 adrp x0, #67162112
67// CHECK4-NEXT: 4023ffc: 21 00 40 f9 ldr x1, [x1]
68// CHECK4-NEXT: 4024000: 04 00 80 14 b #33554448
69// CHECK4-NEXT: 4024004: c0 03 5f d6 ret
66// CHECK4-NEXT: 4213ff8: 60 00 02 b0 adrp x0, #67162112
67// CHECK4-NEXT: 4213ffc: 21 00 40 f9 ldr x1, [x1]
68// CHECK4-NEXT: 4214000: 04 00 80 14 b #33554448
69// CHECK4-NEXT: 4214004: c0 03 5f d6 ret
7070
7171 .section .text.06, "ax", %progbits
7272 .space 32 * 1024 * 1024
7373
74// CHECK5: __CortexA53843419_21000:
75// CHECK5-NEXT: 6024008: 00 00 40 f9 ldr x0, [x0]
76// CHECK5-NEXT: 602400c: fe f7 7f 16 b #-100671496
77// CHECK5: __CortexA53843419_4023000:
78// CHECK5-NEXT: 6024010: 00 00 00 f9 str x0, [x0]
79// CHECK5-NEXT: 6024014: fc ff 7f 17 b #-33554448
74// CHECK5: __CortexA53843419_211000:
75// CHECK5-NEXT: 6214008: 00 00 40 f9 ldr x0, [x0]
76// CHECK5-NEXT: 621400c: fe f7 7f 16 b #-100671496
77// CHECK5: __CortexA53843419_4213000:
78// CHECK5-NEXT: 6214010: 00 00 00 f9 str x0, [x0]
79// CHECK5-NEXT: 6214014: fc ff 7f 17 b #-33554448
8080
8181 .section .text.07, "ax", %progbits
8282 .space (32 * 1024 * 1024) - 12300
......@@ -88,7 +88,7 @@ need_thunk_after_patch:
8888 ret
8989
9090// CHECK6: need_thunk_after_patch:
91// CHECK6-NEXT: 802100c: c0 03 5f d6 ret
91// CHECK6-NEXT: 821100c: c0 03 5f d6 ret
9292
9393 // Will need a patch on pass 2
9494 .section .text.09, "ax", %progbits
......@@ -102,13 +102,13 @@ t3_ffc_ldr:
102102 ret
103103
104104// CHECK7: t3_ffc_ldr:
105// CHECK7-NEXT: 8021ffc: 60 00 00 f0 adrp x0, #61440
106// CHECK7-NEXT: 8022000: 21 00 40 f9 ldr x1, [x1]
107// CHECK7-NEXT: 8022004: 02 00 00 14 b #8
108// CHECK7-NEXT: 8022008: c0 03 5f d6 ret
109// CHECK7: __CortexA53843419_8022004:
110// CHECK7-NEXT: 802200c: 00 00 40 f9 ldr x0, [x0]
111// CHECK7-NEXT: 8022010: fe ff ff 17 b #-8
105// CHECK7-NEXT: 8211ffc: 60 00 00 f0 adrp x0, #61440
106// CHECK7-NEXT: 8212000: 21 00 40 f9 ldr x1, [x1]
107// CHECK7-NEXT: 8212004: 02 00 00 14 b #8
108// CHECK7-NEXT: 8212008: c0 03 5f d6 ret
109// CHECK7: __CortexA53843419_8212004:
110// CHECK7-NEXT: 821200c: 00 00 40 f9 ldr x0, [x0]
111// CHECK7-NEXT: 8212010: fe ff ff 17 b #-8
112112
113113 .section .data
114114 .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 @@
2626// - Optional instruction 3 present or not.
2727// - 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.
3030// CHECK: t3_ff8_ldr:
31// CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #258048
32// CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1]
33// CHECK-FIX: 22000: 03 c8 00 14 b #204812
34// CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0]
35// CHECK-NEXT: 22004: c0 03 5f d6 ret
31// CHECK-NEXT: 211ff8: e0 01 00 f0 adrp x0, #258048
32// CHECK-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
33// CHECK-FIX: 212000: 03 c8 00 14 b #204812
34// CHECK-NOFIX: 212000: 00 00 40 f9 ldr x0, [x0]
35// CHECK-NEXT: 212004: c0 03 5f d6 ret
3636 .section .text.01, "ax", %progbits
3737 .balign 4096
3838 .globl t3_ff8_ldr
......@@ -44,13 +44,13 @@ t3_ff8_ldr:
4444 ldr x0, [x0, :got_lo12:dat1]
4545 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.
4848// CHECK: t3_ff8_ldrsimd:
49// CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #249856
50// CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1]
51// CHECK-FIX: 24000: 05 c0 00 14 b #196628
52// CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8]
53// CHECK-NEXT: 24004: c0 03 5f d6 ret
49// CHECK-NEXT: 213ff8: e0 01 00 b0 adrp x0, #249856
50// CHECK-NEXT: 213ffc: 21 00 40 bd ldr s1, [x1]
51// CHECK-FIX: 214000: 05 c0 00 14 b #196628
52// CHECK-NOFIX: 214000: 02 04 40 f9 ldr x2, [x0, #8]
53// CHECK-NEXT: 214004: c0 03 5f d6 ret
5454 .section .text.02, "ax", %progbits
5555 .balign 4096
5656 .globl t3_ff8_ldrsimd
......@@ -62,13 +62,13 @@ t3_ff8_ldrsimd:
6262 ldr x2, [x0, :got_lo12:dat2]
6363 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.
6666// CHECK: t3_ffc_ldrpost:
67// CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #241664
68// CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #8
69// CHECK-FIX: 26004: 06 b8 00 14 b #188440
70// CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16]
71// CHECK-NEXT: 26008: c0 03 5f d6 ret
67// CHECK-NEXT: 215ffc: c0 01 00 f0 adrp x0, #241664
68// CHECK-NEXT: 216000: 21 84 40 bc ldr s1, [x1], #8
69// CHECK-FIX: 216004: 06 b8 00 14 b #188440
70// CHECK-NOFIX: 216004: 03 08 40 f9 ldr x3, [x0, #16]
71// CHECK-NEXT: 216008: c0 03 5f d6 ret
7272 .section .text.03, "ax", %progbits
7373 .balign 4096
7474 .globl t3_ffc_ldrpost
......@@ -80,13 +80,13 @@ t3_ffc_ldrpost:
8080 ldr x3, [x0, :got_lo12:dat3]
8181 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.
8484// CHECK: t3_ff8_strpre:
85// CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #233472
86// CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]!
87// CHECK-FIX: 28000: 09 b0 00 14 b #180260
88// CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0]
89// CHECK-NEXT: 28004: c0 03 5f d6 ret
85// CHECK-NEXT: 217ff8: c0 01 00 b0 adrp x0, #233472
86// CHECK-NEXT: 217ffc: 21 8c 00 bc str s1, [x1, #8]!
87// CHECK-FIX: 218000: 09 b0 00 14 b #180260
88// CHECK-NOFIX: 218000: 02 00 40 f9 ldr x2, [x0]
89// CHECK-NEXT: 218004: c0 03 5f d6 ret
9090 .section .text.04, "ax", %progbits
9191 .balign 4096
9292 .globl t3_ff8_strpre
......@@ -98,13 +98,13 @@ t3_ff8_strpre:
9898 ldr x2, [x0, :lo12:dat1]
9999 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.
102102// CHECK: t3_ffc_str:
103// CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280
104// CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2]
105// CHECK-FIX: 2a004: 0a a8 00 14 b #172072
106// CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8]
107// CHECK-NEXT: 2a008: c0 03 5f d6 ret
103// CHECK-NEXT: 219ffc: bc 01 00 f0 adrp x28, #225280
104// CHECK-NEXT: 21a000: 42 00 00 f9 str x2, [x2]
105// CHECK-FIX: 21a004: 0a a8 00 14 b #172072
106// CHECK-NOFIX: 21a004: 9c 07 00 f9 str x28, [x28, #8]
107// CHECK-NEXT: 21a008: c0 03 5f d6 ret
108108 .section .text.05, "ax", %progbits
109109 .balign 4096
110110 .globl t3_ffc_str
......@@ -116,13 +116,13 @@ t3_ffc_str:
116116 str x28, [x28, :lo12:dat2]
117117 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.
120120// CHECK: t3_ffc_strsimd:
121// CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088
122// CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2]
123// CHECK-FIX: 2c004: 0c a0 00 14 b #163888
124// CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16]
125// CHECK-NEXT: 2c008: c0 03 5f d6 ret
121// CHECK-NEXT: 21bffc: bc 01 00 b0 adrp x28, #217088
122// CHECK-NEXT: 21c000: 44 00 00 b9 str w4, [x2]
123// CHECK-FIX: 21c004: 0c a0 00 14 b #163888
124// CHECK-NOFIX: 21c004: 84 0b 00 f9 str x4, [x28, #16]
125// CHECK-NEXT: 21c008: c0 03 5f d6 ret
126126 .section .text.06, "ax", %progbits
127127 .balign 4096
128128 .globl t3_ffc_strsimd
......@@ -134,13 +134,13 @@ t3_ffc_strsimd:
134134 str x4, [x28, :lo12:dat3]
135135 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.
138138// CHECK: t3_ff8_ldrunpriv:
139// CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896
140// CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2]
141// CHECK-FIX: 2e000: 0f 98 00 14 b #155708
142// CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29]
143// CHECK-NEXT: 2e004: c0 03 5f d6 ret
139// CHECK-NEXT: 21dff8: 9d 01 00 f0 adrp x29, #208896
140// CHECK-NEXT: 21dffc: 41 08 40 38 ldtrb w1, [x2]
141// CHECK-FIX: 21e000: 0f 98 00 14 b #155708
142// CHECK-NOFIX: 21e000: bd 03 40 f9 ldr x29, [x29]
143// CHECK-NEXT: 21e004: c0 03 5f d6 ret
144144 .section .text.07, "ax", %progbits
145145 .balign 4096
146146 .globl t3_ff8_ldrunpriv
......@@ -152,13 +152,13 @@ t3_ff8_ldrunpriv:
152152 ldr x29, [x29, :got_lo12:dat1]
153153 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.
156156// CHECK: t3_ffc_ldur:
157// CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704
158// CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4]
159// CHECK-FIX: 30004: 10 90 00 14 b #147520
160// CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8]
161// CHECK-NEXT: 30008: c0 03 5f d6 ret
157// CHECK-NEXT: 21fffc: 9d 01 00 b0 adrp x29, #200704
158// CHECK-NEXT: 220000: 42 40 40 b8 ldur w2, [x2, #4]
159// CHECK-FIX: 220004: 10 90 00 14 b #147520
160// CHECK-NOFIX: 220004: bd 07 40 f9 ldr x29, [x29, #8]
161// CHECK-NEXT: 220008: c0 03 5f d6 ret
162162 .balign 4096
163163 .globl t3_ffc_ldur
164164 .type t3_ffc_ldur, %function
......@@ -169,13 +169,13 @@ t3_ffc_ldur:
169169 ldr x29, [x29, :got_lo12:dat2]
170170 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.
173173// CHECK: t3_ffc_sturh:
174// CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512
175// CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4]
176// CHECK-FIX: 32004: 12 88 00 14 b #139336
177// CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16]
178// CHECK-NEXT: 32008: c0 03 5f d6 ret
174// CHECK-NEXT: 221ffc: 72 01 00 f0 adrp x18, #192512
175// CHECK-NEXT: 222000: 43 40 00 78 sturh w3, [x2, #4]
176// CHECK-FIX: 222004: 12 88 00 14 b #139336
177// CHECK-NOFIX: 222004: 41 0a 40 f9 ldr x1, [x18, #16]
178// CHECK-NEXT: 222008: c0 03 5f d6 ret
179179 .section .text.09, "ax", %progbits
180180 .balign 4096
181181 .globl t3_ffc_sturh
......@@ -187,13 +187,13 @@ t3_ffc_sturh:
187187 ldr x1, [x18, :got_lo12:dat3]
188188 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.
191191// CHECK: t3_ff8_literal:
192// CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320
193// CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4
194// CHECK-FIX: 34000: 15 80 00 14 b #131156
195// CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18]
196// CHECK-NEXT: 34004: c0 03 5f d6 ret
192// CHECK-NEXT: 223ff8: 72 01 00 b0 adrp x18, #184320
193// CHECK-NEXT: 223ffc: e3 ff ff 58 ldr x3, #-4
194// CHECK-FIX: 224000: 15 80 00 14 b #131156
195// CHECK-NOFIX: 224000: 52 02 40 f9 ldr x18, [x18]
196// CHECK-NEXT: 224004: c0 03 5f d6 ret
197197 .section .text.10, "ax", %progbits
198198 .balign 4096
199199 .globl t3_ff8_literal
......@@ -205,13 +205,13 @@ t3_ff8_literal:
205205 ldr x18, [x18, :lo12:dat1]
206206 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.
209209// CHECK: t3_ffc_register:
210// CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128
211// CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1]
212// CHECK-FIX: 36004: 16 78 00 14 b #122968
213// CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8]
214// CHECK-NEXT: 36008: c0 03 5f d6 ret
210// CHECK-NEXT: 225ffc: 4f 01 00 f0 adrp x15, #176128
211// CHECK-NEXT: 226000: 43 68 61 f8 ldr x3, [x2, x1]
212// CHECK-FIX: 226004: 16 78 00 14 b #122968
213// CHECK-NOFIX: 226004: ea 05 40 f9 ldr x10, [x15, #8]
214// CHECK-NEXT: 226008: c0 03 5f d6 ret
215215 .section .text.11, "ax", %progbits
216216 .balign 4096
217217 .globl t3_ffc_register
......@@ -223,13 +223,13 @@ t3_ffc_register:
223223 ldr x10, [x15, :lo12:dat2]
224224 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.
227227// CHECK: t3_ff8_stp:
228// CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936
229// CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3]
230// CHECK-FIX: 38000: 19 70 00 14 b #114788
231// CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16]
232// CHECK-NEXT: 38004: c0 03 5f d6 ret
228// CHECK-NEXT: 227ff8: 50 01 00 b0 adrp x16, #167936
229// CHECK-NEXT: 227ffc: 61 08 00 a9 stp x1, x2, [x3]
230// CHECK-FIX: 228000: 19 70 00 14 b #114788
231// CHECK-NOFIX: 228000: 0d 0a 40 f9 ldr x13, [x16, #16]
232// CHECK-NEXT: 228004: c0 03 5f d6 ret
233233 .section .text.12, "ax", %progbits
234234 .balign 4096
235235 .globl t3_ff8_stp
......@@ -241,13 +241,13 @@ t3_ff8_stp:
241241 ldr x13, [x16, :lo12:dat3]
242242 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.
245245// CHECK: t3_ffc_stnp:
246// CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744
247// CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3]
248// CHECK-FIX: 3a004: 1a 68 00 14 b #106600
249// CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7]
250// CHECK-NEXT: 3a008: c0 03 5f d6 ret
246// CHECK-NEXT: 229ffc: 27 01 00 f0 adrp x7, #159744
247// CHECK-NEXT: 22a000: 61 08 00 a8 stnp x1, x2, [x3]
248// CHECK-FIX: 22a004: 1a 68 00 14 b #106600
249// CHECK-NOFIX: 22a004: e9 00 40 f9 ldr x9, [x7]
250// CHECK-NEXT: 22a008: c0 03 5f d6 ret
251251 .section .text.13, "ax", %progbits
252252 .balign 4096
253253 .globl t3_ffc_stnp
......@@ -259,13 +259,13 @@ t3_ffc_stnp:
259259 ldr x9, [x7, :lo12:dat1]
260260 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.
263263// CHECK: t3_ffc_st1singlepost:
264// CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552
265// CHECK-NEXT: 3c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2
266// CHECK-FIX: 3c004: 1c 60 00 14 b #98416
267// CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8]
268// CHECK-NEXT: 3c008: c0 03 5f d6 ret
264// CHECK-NEXT: 22bffc: 37 01 00 b0 adrp x23, #151552
265// CHECK-NEXT: 22c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2
266// CHECK-FIX: 22c004: 1c 60 00 14 b #98416
267// CHECK-NOFIX: 22c004: f6 06 40 f9 ldr x22, [x23, #8]
268// CHECK-NEXT: 22c008: c0 03 5f d6 ret
269269 .section .text.14, "ax", %progbits
270270 .balign 4096
271271 .globl t3_ffc_st1singlepost
......@@ -277,13 +277,13 @@ t3_ffc_st1singlepost:
277277 ldr x22, [x23, :lo12:dat2]
278278 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.
281281// CHECK: t3_ff8_st1multiple:
282// CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360
283// CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1]
284// CHECK-FIX: 3e000: 1f 58 00 14 b #90236
285// CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16]
286// CHECK-NEXT: 3e004: c0 03 5f d6 ret
282// CHECK-NEXT: 22dff8: 17 01 00 f0 adrp x23, #143360
283// CHECK-NEXT: 22dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1]
284// CHECK-FIX: 22e000: 1f 58 00 14 b #90236
285// CHECK-NOFIX: 22e000: f8 0a 40 f9 ldr x24, [x23, #16]
286// CHECK-NEXT: 22e004: c0 03 5f d6 ret
287287 .section .text.15, "ax", %progbits
288288 .balign 4096
289289 .globl t3_ff8_st1multiple
......@@ -295,14 +295,14 @@ t3_ff8_st1multiple:
295295 ldr x24, [x23, :lo12:dat3]
296296 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.
299299// CHECK: t4_ff8_ldr:
300// CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168
301// CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1]
302// CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0
303// CHECK-FIX: 40004: 20 50 00 14 b #82048
304// CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0]
305// CHECK-NEXT: 40008: c0 03 5f d6 ret
300// CHECK-NEXT: 22fff8: 00 01 00 b0 adrp x0, #135168
301// CHECK-NEXT: 22fffc: 21 00 40 f9 ldr x1, [x1]
302// CHECK-NEXT: 230000: 42 00 00 8b add x2, x2, x0
303// CHECK-FIX: 230004: 20 50 00 14 b #82048
304// CHECK-NOFIX: 230004: 02 00 40 f9 ldr x2, [x0]
305// CHECK-NEXT: 230008: c0 03 5f d6 ret
306306 .section .text.16, "ax", %progbits
307307 .balign 4096
308308 .globl t4_ff8_ldr
......@@ -315,14 +315,14 @@ t4_ff8_ldr:
315315 ldr x2, [x0, :got_lo12:dat1]
316316 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.
319319// CHECK: t4_ffc_str:
320// CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976
321// CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2]
322// CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2
323// CHECK-FIX: 42008: 21 48 00 14 b #73860
324// CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8]
325// CHECK-NEXT: 4200c: c0 03 5f d6 ret
320// CHECK-NEXT: 231ffc: fc 00 00 f0 adrp x28, #126976
321// CHECK-NEXT: 232000: 42 00 00 f9 str x2, [x2]
322// CHECK-NEXT: 232004: 20 00 02 cb sub x0, x1, x2
323// CHECK-FIX: 232008: 21 48 00 14 b #73860
324// CHECK-NOFIX: 232008: 9b 07 00 f9 str x27, [x28, #8]
325// CHECK-NEXT: 23200c: c0 03 5f d6 ret
326326 .section .text.17, "ax", %progbits
327327 .balign 4096
328328 .globl t4_ffc_str
......@@ -335,14 +335,14 @@ t4_ffc_str:
335335 str x27, [x28, :got_lo12:dat2]
336336 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.
339339// CHECK: t4_ff8_stp:
340// CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784
341// CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3]
342// CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16
343// CHECK-FIX: 44004: 24 40 00 14 b #65680
344// CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16]
345// CHECK-NEXT: 44008: c0 03 5f d6 ret
340// CHECK-NEXT: 233ff8: f0 00 00 b0 adrp x16, #118784
341// CHECK-NEXT: 233ffc: 61 08 00 a9 stp x1, x2, [x3]
342// CHECK-NEXT: 234000: 03 7e 10 9b mul x3, x16, x16
343// CHECK-FIX: 234004: 24 40 00 14 b #65680
344// CHECK-NOFIX: 234004: 0e 0a 40 f9 ldr x14, [x16, #16]
345// CHECK-NEXT: 234008: c0 03 5f d6 ret
346346 .section .text.18, "ax", %progbits
347347 .balign 4096
348348 .globl t4_ff8_stp
......@@ -355,14 +355,14 @@ t4_ff8_stp:
355355 ldr x14, [x16, :got_lo12:dat3]
356356 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.
359359// CHECK: t4_ff8_stppre:
360// CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592
361// CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]!
362// CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16
363// CHECK-FIX: 46004: 26 38 00 14 b #57496
364// CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8]
365// CHECK-NEXT: 46008: c0 03 5f d6 ret
360// CHECK-NEXT: 235ff8: d0 00 00 f0 adrp x16, #110592
361// CHECK-NEXT: 235ffc: 61 08 81 a9 stp x1, x2, [x3, #16]!
362// CHECK-NEXT: 236000: 03 7e 10 9b mul x3, x16, x16
363// CHECK-FIX: 236004: 26 38 00 14 b #57496
364// CHECK-NOFIX: 236004: 0e 06 40 f9 ldr x14, [x16, #8]
365// CHECK-NEXT: 236008: c0 03 5f d6 ret
366366 .section .text.19, "ax", %progbits
367367 .balign 4096
368368 .globl t4_ff8_stppre
......@@ -375,14 +375,14 @@ t4_ff8_stppre:
375375 ldr x14, [x16, #8]
376376 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.
379379// CHECK: t4_ff8_stppost:
380// CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400
381// CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16
382// CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16
383// CHECK-FIX: 48004: 28 30 00 14 b #49312
384// CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8]
385// CHECK-NEXT: 48008: c0 03 5f d6 ret
380// CHECK-NEXT: 237ff8: d0 00 00 b0 adrp x16, #102400
381// CHECK-NEXT: 237ffc: 61 08 81 a8 stp x1, x2, [x3], #16
382// CHECK-NEXT: 238000: 03 7e 10 9b mul x3, x16, x16
383// CHECK-FIX: 238004: 28 30 00 14 b #49312
384// CHECK-NOFIX: 238004: 0e 06 40 f9 ldr x14, [x16, #8]
385// CHECK-NEXT: 238008: c0 03 5f d6 ret
386386 .section .text.20, "ax", %progbits
387387 .balign 4096
388388 .globl t4_ff8_stppost
......@@ -395,14 +395,14 @@ t4_ff8_stppost:
395395 ldr x14, [x16, #8]
396396 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.
399399// CHECK: t4_ffc_stpsimd:
400// CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208
401// CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3]
402// CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16
403// CHECK-FIX: 4a008: 29 28 00 14 b #41124
404// CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8]
405// CHECK-NEXT: 4a00c: c0 03 5f d6 ret
400// CHECK-NEXT: 239ffc: b0 00 00 f0 adrp x16, #94208
401// CHECK-NEXT: 23a000: 61 08 00 ad stp q1, q2, [x3]
402// CHECK-NEXT: 23a004: 03 7e 10 9b mul x3, x16, x16
403// CHECK-FIX: 23a008: 29 28 00 14 b #41124
404// CHECK-NOFIX: 23a008: 0e 06 40 f9 ldr x14, [x16, #8]
405// CHECK-NEXT: 23a00c: c0 03 5f d6 ret
406406 .section .text.21, "ax", %progbits
407407 .balign 4096
408408 .globl t4_ffc_stpsimd
......@@ -415,14 +415,14 @@ t4_ffc_stpsimd:
415415 ldr x14, [x16, #8]
416416 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.
419419// CHECK: t4_ffc_stnp:
420// CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016
421// CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3]
422// CHECK-NEXT: 4c004: 1f 20 03 d5 nop
423// CHECK-FIX: 4c008: 2b 20 00 14 b #32940
424// CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7]
425// CHECK-NEXT: 4c00c: c0 03 5f d6 ret
420// CHECK-NEXT: 23bffc: a7 00 00 b0 adrp x7, #86016
421// CHECK-NEXT: 23c000: 61 08 00 a8 stnp x1, x2, [x3]
422// CHECK-NEXT: 23c004: 1f 20 03 d5 nop
423// CHECK-FIX: 23c008: 2b 20 00 14 b #32940
424// CHECK-NOFIX: 23c008: ea 00 40 f9 ldr x10, [x7]
425// CHECK-NEXT: 23c00c: c0 03 5f d6 ret
426426 .section .text.22, "ax", %progbits
427427 .balign 4096
428428 .globl t4_ffc_stnp
......@@ -435,14 +435,14 @@ t4_ffc_stnp:
435435 ldr x10, [x7, :got_lo12:dat1]
436436 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.
439439// CHECK: t4_ffc_st1:
440// CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824
441// CHECK-NEXT: 4e000: 20 80 00 4d st1 { v0.s }[2], [x1]
442// CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8]
443// CHECK-FIX: 4e008: 2d 18 00 14 b #24756
444// CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760]
445// CHECK-NEXT: 4e00c: c0 03 5f d6 ret
440// CHECK-NEXT: 23dffc: 98 00 00 f0 adrp x24, #77824
441// CHECK-NEXT: 23e000: 20 80 00 4d st1 { v0.s }[2], [x1]
442// CHECK-NEXT: 23e004: f6 06 40 f9 ldr x22, [x23, #8]
443// CHECK-FIX: 23e008: 2d 18 00 14 b #24756
444// CHECK-NOFIX: 23e008: 18 ff 3f f9 str x24, [x24, #32760]
445// CHECK-NEXT: 23e00c: c0 03 5f d6 ret
446446 .section .text.23, "ax", %progbits
447447 .balign 4096
448448 .globl t4_ffc_st1
......@@ -455,14 +455,14 @@ t4_ffc_st1:
455455 str x24, [x24, #32760]
456456 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.
459459// CHECK: t3_ff8_ldr_once:
460// CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632
461// CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2
462// CHECK-FIX: 50000: 31 10 00 14 b #16580
463// CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16]
464// CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16]
465// CHECK-NEXT: 50008: c0 03 5f d6 ret
460// CHECK-NEXT: 23fff8: 80 00 00 b0 adrp x0, #69632
461// CHECK-NEXT: 23fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2
462// CHECK-FIX: 240000: 31 10 00 14 b #16580
463// CHECK-NOFIX: 240000: 01 08 40 f9 ldr x1, [x0, #16]
464// CHECK-NEXT: 240004: 02 08 40 f9 ldr x2, [x0, #16]
465// CHECK-NEXT: 240008: c0 03 5f d6 ret
466466 .section .text.24, "ax", %progbits
467467 .balign 4096
468468 .globl t3_ff8_ldr_once
......@@ -475,14 +475,14 @@ t3_ff8_ldr_once:
475475 ldr x2, [x0, #16]
476476 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.
479479// CHECK: t3_ff8_ldxr:
480// CHECK-NEXT: 51ff8: 60 00 00 f0 adrp x0, #61440
481// CHECK-NEXT: 51ffc: 03 7c 5f c8 ldxr x3, [x0]
482// CHECK-FIX: 52000: 33 08 00 14 b #8396
483// CHECK-NOFIX: 52000: 01 08 40 f9 ldr x1, [x0, #16]
484// CHECK: 52004: 02 08 40 f9 ldr x2, [x0, #16]
485// CHECK-NEXT: 52008: c0 03 5f d6 ret
480// CHECK-NEXT: 241ff8: 60 00 00 f0 adrp x0, #61440
481// CHECK-NEXT: 241ffc: 03 7c 5f c8 ldxr x3, [x0]
482// CHECK-FIX: 242000: 33 08 00 14 b #8396
483// CHECK-NOFIX: 242000: 01 08 40 f9 ldr x1, [x0, #16]
484// CHECK: 242004: 02 08 40 f9 ldr x2, [x0, #16]
485// CHECK-NEXT: 242008: c0 03 5f d6 ret
486486 .section .text.25, "ax", %progbits
487487 .balign 4096
488488 .globl t3_ff8_ldxr
......@@ -495,14 +495,14 @@ t3_ff8_ldxr:
495495 ldr x2, [x0, #16]
496496 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.
499499// CHECK: t3_ff8_stxr:
500// CHECK-NEXT: 53ff8: 60 00 00 b0 adrp x0, #53248
501// CHECK-NEXT: 53ffc: 03 7c 04 c8 stxr w4, x3, [x0]
502// CHECK-FIX: 54000: 35 00 00 14 b #212
503// CHECK-NOFIX: 54000: 01 08 40 f9 ldr x1, [x0, #16]
504// CHECK: 54004: 02 08 40 f9 ldr x2, [x0, #16]
505// CHECK-NEXT: 54008: c0 03 5f d6 ret
500// CHECK-NEXT: 243ff8: 60 00 00 b0 adrp x0, #53248
501// CHECK-NEXT: 243ffc: 03 7c 04 c8 stxr w4, x3, [x0]
502// CHECK-FIX: 244000: 35 00 00 14 b #212
503// CHECK-NOFIX: 244000: 01 08 40 f9 ldr x1, [x0, #16]
504// CHECK: 244004: 02 08 40 f9 ldr x2, [x0, #16]
505// CHECK-NEXT: 244008: c0 03 5f d6 ret
506506 .section .text.26, "ax", %progbits
507507 .balign 4096
508508 .globl t3_ff8_stxr
......@@ -521,84 +521,84 @@ t3_ff8_stxr:
521521_start:
522522 ret
523523
524// CHECK-FIX: __CortexA53843419_22000:
525// CHECK-FIX-NEXT: 5400c: 00 00 40 f9 ldr x0, [x0]
526// CHECK-FIX-NEXT: 54010: fd 37 ff 17 b #-204812
527// CHECK-FIX: __CortexA53843419_24000:
528// CHECK-FIX-NEXT: 54014: 02 04 40 f9 ldr x2, [x0, #8]
529// CHECK-FIX-NEXT: 54018: fb 3f ff 17 b #-196628
530// CHECK-FIX: __CortexA53843419_26004:
531// CHECK-FIX-NEXT: 5401c: 03 08 40 f9 ldr x3, [x0, #16]
532// CHECK-FIX-NEXT: 54020: fa 47 ff 17 b #-188440
533// CHECK-FIX: __CortexA53843419_28000:
534// CHECK-FIX-NEXT: 54024: 02 00 40 f9 ldr x2, [x0]
535// CHECK-FIX-NEXT: 54028: f7 4f ff 17 b #-180260
536// CHECK-FIX: __CortexA53843419_2A004:
537// CHECK-FIX-NEXT: 5402c: 9c 07 00 f9 str x28, [x28, #8]
538// CHECK-FIX-NEXT: 54030: f6 57 ff 17 b #-172072
539// CHECK-FIX: __CortexA53843419_2C004:
540// CHECK-FIX-NEXT: 54034: 84 0b 00 f9 str x4, [x28, #16]
541// CHECK-FIX-NEXT: 54038: f4 5f ff 17 b #-163888
542// CHECK-FIX: __CortexA53843419_2E000:
543// CHECK-FIX-NEXT: 5403c: bd 03 40 f9 ldr x29, [x29]
544// CHECK-FIX-NEXT: 54040: f1 67 ff 17 b #-155708
545// CHECK-FIX: __CortexA53843419_30004:
546// CHECK-FIX-NEXT: 54044: bd 07 40 f9 ldr x29, [x29, #8]
547// CHECK-FIX-NEXT: 54048: f0 6f ff 17 b #-147520
548// CHECK-FIX: __CortexA53843419_32004:
549// CHECK-FIX-NEXT: 5404c: 41 0a 40 f9 ldr x1, [x18, #16]
550// CHECK-FIX-NEXT: 54050: ee 77 ff 17 b #-139336
551// CHECK-FIX: __CortexA53843419_34000:
552// CHECK-FIX-NEXT: 54054: 52 02 40 f9 ldr x18, [x18]
553// CHECK-FIX-NEXT: 54058: eb 7f ff 17 b #-131156
554// CHECK-FIX: __CortexA53843419_36004:
555// CHECK-FIX-NEXT: 5405c: ea 05 40 f9 ldr x10, [x15, #8]
556// CHECK-FIX-NEXT: 54060: ea 87 ff 17 b #-122968
557// CHECK-FIX: __CortexA53843419_38000:
558// CHECK-FIX-NEXT: 54064: 0d 0a 40 f9 ldr x13, [x16, #16]
559// CHECK-FIX-NEXT: 54068: e7 8f ff 17 b #-114788
560// CHECK-FIX: __CortexA53843419_3A004:
561// CHECK-FIX-NEXT: 5406c: e9 00 40 f9 ldr x9, [x7]
562// CHECK-FIX-NEXT: 54070: e6 97 ff 17 b #-106600
563// CHECK-FIX: __CortexA53843419_3C004:
564// CHECK-FIX-NEXT: 54074: f6 06 40 f9 ldr x22, [x23, #8]
565// CHECK-FIX-NEXT: 54078: e4 9f ff 17 b #-98416
566// CHECK-FIX: __CortexA53843419_3E000:
567// CHECK-FIX-NEXT: 5407c: f8 0a 40 f9 ldr x24, [x23, #16]
568// CHECK-FIX-NEXT: 54080: e1 a7 ff 17 b #-90236
569// CHECK-FIX: __CortexA53843419_40004:
570// CHECK-FIX-NEXT: 54084: 02 00 40 f9 ldr x2, [x0]
571// CHECK-FIX-NEXT: 54088: e0 af ff 17 b #-82048
572// CHECK-FIX: __CortexA53843419_42008:
573// CHECK-FIX-NEXT: 5408c: 9b 07 00 f9 str x27, [x28, #8]
574// CHECK-FIX-NEXT: 54090: df b7 ff 17 b #-73860
575// CHECK-FIX: __CortexA53843419_44004:
576// CHECK-FIX-NEXT: 54094: 0e 0a 40 f9 ldr x14, [x16, #16]
577// CHECK-FIX-NEXT: 54098: dc bf ff 17 b #-65680
578// CHECK-FIX: __CortexA53843419_46004:
579// CHECK-FIX-NEXT: 5409c: 0e 06 40 f9 ldr x14, [x16, #8]
580// CHECK-FIX-NEXT: 540a0: da c7 ff 17 b #-57496
581// CHECK-FIX: __CortexA53843419_48004:
582// CHECK-FIX-NEXT: 540a4: 0e 06 40 f9 ldr x14, [x16, #8]
583// CHECK-FIX-NEXT: 540a8: d8 cf ff 17 b #-49312
584// CHECK-FIX: __CortexA53843419_4A008:
585// CHECK-FIX-NEXT: 540ac: 0e 06 40 f9 ldr x14, [x16, #8]
586// CHECK-FIX-NEXT: 540b0: d7 d7 ff 17 b #-41124
587// CHECK-FIX: __CortexA53843419_4C008:
588// CHECK-FIX-NEXT: 540b4: ea 00 40 f9 ldr x10, [x7]
589// CHECK-FIX-NEXT: 540b8: d5 df ff 17 b #-32940
590// CHECK-FIX: __CortexA53843419_4E008:
591// CHECK-FIX-NEXT: 540bc: 18 ff 3f f9 str x24, [x24, #32760]
592// CHECK-FIX-NEXT: 540c0: d3 e7 ff 17 b #-24756
593// CHECK-FIX: __CortexA53843419_50000:
594// CHECK-FIX-NEXT: 540c4: 01 08 40 f9 ldr x1, [x0, #16]
595// CHECK-FIX-NEXT: 540c8: cf ef ff 17 b #-16580
596// CHECK-FIX: __CortexA53843419_52000:
597// CHECK-FIX-NEXT: 540cc: 01 08 40 f9 ldr x1, [x0, #16]
598// CHECK-FIX-NEXT: 540d0: cd f7 ff 17 b #-8396
599// CHECK-FIX: __CortexA53843419_54000:
600// CHECK-FIX-NEXT: 540d4: 01 08 40 f9 ldr x1, [x0, #16]
601// CHECK-FIX-NEXT: 540d8: cb ff ff 17 b #-212
524// CHECK-FIX: __CortexA53843419_212000:
525// CHECK-FIX-NEXT: 24400c: 00 00 40 f9 ldr x0, [x0]
526// CHECK-FIX-NEXT: 244010: fd 37 ff 17 b #-204812
527// CHECK-FIX: __CortexA53843419_214000:
528// CHECK-FIX-NEXT: 244014: 02 04 40 f9 ldr x2, [x0, #8]
529// CHECK-FIX-NEXT: 244018: fb 3f ff 17 b #-196628
530// CHECK-FIX: __CortexA53843419_216004:
531// CHECK-FIX-NEXT: 24401c: 03 08 40 f9 ldr x3, [x0, #16]
532// CHECK-FIX-NEXT: 244020: fa 47 ff 17 b #-188440
533// CHECK-FIX: __CortexA53843419_218000:
534// CHECK-FIX-NEXT: 244024: 02 00 40 f9 ldr x2, [x0]
535// CHECK-FIX-NEXT: 244028: f7 4f ff 17 b #-180260
536// CHECK-FIX: __CortexA53843419_21A004:
537// CHECK-FIX-NEXT: 24402c: 9c 07 00 f9 str x28, [x28, #8]
538// CHECK-FIX-NEXT: 244030: f6 57 ff 17 b #-172072
539// CHECK-FIX: __CortexA53843419_21C004:
540// CHECK-FIX-NEXT: 244034: 84 0b 00 f9 str x4, [x28, #16]
541// CHECK-FIX-NEXT: 244038: f4 5f ff 17 b #-163888
542// CHECK-FIX: __CortexA53843419_21E000:
543// CHECK-FIX-NEXT: 24403c: bd 03 40 f9 ldr x29, [x29]
544// CHECK-FIX-NEXT: 244040: f1 67 ff 17 b #-155708
545// CHECK-FIX: __CortexA53843419_220004:
546// CHECK-FIX-NEXT: 244044: bd 07 40 f9 ldr x29, [x29, #8]
547// CHECK-FIX-NEXT: 244048: f0 6f ff 17 b #-147520
548// CHECK-FIX: __CortexA53843419_222004:
549// CHECK-FIX-NEXT: 24404c: 41 0a 40 f9 ldr x1, [x18, #16]
550// CHECK-FIX-NEXT: 244050: ee 77 ff 17 b #-139336
551// CHECK-FIX: __CortexA53843419_224000:
552// CHECK-FIX-NEXT: 244054: 52 02 40 f9 ldr x18, [x18]
553// CHECK-FIX-NEXT: 244058: eb 7f ff 17 b #-131156
554// CHECK-FIX: __CortexA53843419_226004:
555// CHECK-FIX-NEXT: 24405c: ea 05 40 f9 ldr x10, [x15, #8]
556// CHECK-FIX-NEXT: 244060: ea 87 ff 17 b #-122968
557// CHECK-FIX: __CortexA53843419_228000:
558// CHECK-FIX-NEXT: 244064: 0d 0a 40 f9 ldr x13, [x16, #16]
559// CHECK-FIX-NEXT: 244068: e7 8f ff 17 b #-114788
560// CHECK-FIX: __CortexA53843419_22A004:
561// CHECK-FIX-NEXT: 24406c: e9 00 40 f9 ldr x9, [x7]
562// CHECK-FIX-NEXT: 244070: e6 97 ff 17 b #-106600
563// CHECK-FIX: __CortexA53843419_22C004:
564// CHECK-FIX-NEXT: 244074: f6 06 40 f9 ldr x22, [x23, #8]
565// CHECK-FIX-NEXT: 244078: e4 9f ff 17 b #-98416
566// CHECK-FIX: __CortexA53843419_22E000:
567// CHECK-FIX-NEXT: 24407c: f8 0a 40 f9 ldr x24, [x23, #16]
568// CHECK-FIX-NEXT: 244080: e1 a7 ff 17 b #-90236
569// CHECK-FIX: __CortexA53843419_230004:
570// CHECK-FIX-NEXT: 244084: 02 00 40 f9 ldr x2, [x0]
571// CHECK-FIX-NEXT: 244088: e0 af ff 17 b #-82048
572// CHECK-FIX: __CortexA53843419_232008:
573// CHECK-FIX-NEXT: 24408c: 9b 07 00 f9 str x27, [x28, #8]
574// CHECK-FIX-NEXT: 244090: df b7 ff 17 b #-73860
575// CHECK-FIX: __CortexA53843419_234004:
576// CHECK-FIX-NEXT: 244094: 0e 0a 40 f9 ldr x14, [x16, #16]
577// CHECK-FIX-NEXT: 244098: dc bf ff 17 b #-65680
578// CHECK-FIX: __CortexA53843419_236004:
579// CHECK-FIX-NEXT: 24409c: 0e 06 40 f9 ldr x14, [x16, #8]
580// CHECK-FIX-NEXT: 2440a0: da c7 ff 17 b #-57496
581// CHECK-FIX: __CortexA53843419_238004:
582// CHECK-FIX-NEXT: 2440a4: 0e 06 40 f9 ldr x14, [x16, #8]
583// CHECK-FIX-NEXT: 2440a8: d8 cf ff 17 b #-49312
584// CHECK-FIX: __CortexA53843419_23A008:
585// CHECK-FIX-NEXT: 2440ac: 0e 06 40 f9 ldr x14, [x16, #8]
586// CHECK-FIX-NEXT: 2440b0: d7 d7 ff 17 b #-41124
587// CHECK-FIX: __CortexA53843419_23C008:
588// CHECK-FIX-NEXT: 2440b4: ea 00 40 f9 ldr x10, [x7]
589// CHECK-FIX-NEXT: 2440b8: d5 df ff 17 b #-32940
590// CHECK-FIX: __CortexA53843419_23E008:
591// CHECK-FIX-NEXT: 2440bc: 18 ff 3f f9 str x24, [x24, #32760]
592// CHECK-FIX-NEXT: 2440c0: d3 e7 ff 17 b #-24756
593// CHECK-FIX: __CortexA53843419_240000:
594// CHECK-FIX-NEXT: 2440c4: 01 08 40 f9 ldr x1, [x0, #16]
595// CHECK-FIX-NEXT: 2440c8: cf ef ff 17 b #-16580
596// CHECK-FIX: __CortexA53843419_242000:
597// CHECK-FIX-NEXT: 2440cc: 01 08 40 f9 ldr x1, [x0, #16]
598// CHECK-FIX-NEXT: 2440d0: cd f7 ff 17 b #-8396
599// CHECK-FIX: __CortexA53843419_244000:
600// CHECK-FIX-NEXT: 2440d4: 01 08 40 f9 ldr x1, [x0, #16]
601// CHECK-FIX-NEXT: 2440d8: cb ff ff 17 b #-212
602602 .data
603603 .globl dat
604604 .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:
1212// S = 0x100, A = 0x24
1313// S + A = 0x124
1414// CHECK: Contents of section .R_AARCH64_ABS64:
15// CHECK-NEXT: 20000 24010000 00000000
15// CHECK-NEXT: 210000 24010000 00000000
1616
1717.section .R_AARCH64_PREL64, "ax",@progbits
1818 .xword foo - . + 0x24
......@@ -20,4 +20,4 @@ _start:
2020// S = 0x100, A = 0x24, P = 0x20008
2121// S + A - P = 0xfffffffffffe011c
2222// CHECK: Contents of section .R_AARCH64_PREL64:
23// CHECK-NEXT: 20008 1c01feff ffffffff
23// 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 @@
1010// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
1111// CHECK: Relocations [
1212// CHECK-NEXT: Section (4) .rela.plt {
13// CHECK: 0x30018 R_AARCH64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x20000
16// CHECK-NEXT: 0x30030 R_AARCH64_IRELATIVE - 0x20004
13// CHECK: 0x220018 R_AARCH64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x220020 R_AARCH64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x220028 R_AARCH64_IRELATIVE - 0x210000
16// CHECK-NEXT: 0x220030 R_AARCH64_IRELATIVE - 0x210004
1717// CHECK-NEXT: }
1818// CHECK-NEXT: ]
1919
2020// Check that .got.plt entries point back to PLT header
2121// GOTPLT: Contents of section .got.plt:
22// GOTPLT-NEXT: 30000 00000000 00000000 00000000 00000000
23// GOTPLT-NEXT: 30010 00000000 00000000 20000200 00000000
24// GOTPLT-NEXT: 30020 20000200 00000000 20000200 00000000
25// GOTPLT-NEXT: 30030 20000200 00000000
22// GOTPLT-NEXT: 220000 00000000 00000000 00000000 00000000
23// GOTPLT-NEXT: 220010 00000000 00000000 20002100 00000000
24// GOTPLT-NEXT: 220020 20002100 00000000 20002100 00000000
25// GOTPLT-NEXT: 220030 20002100 00000000
2626
2727// Check that the PLTRELSZ tag includes the IRELATIVE relocations
2828// CHECK: DynamicSection [
......@@ -31,40 +31,44 @@
3131// Check that a PLT header is written and the ifunc entries appear last
3232// DISASM: Disassembly of section .text:
3333// DISASM-NEXT: foo:
34// DISASM-NEXT: 20000: {{.*}} ret
34// DISASM-NEXT: 210000: {{.*}} ret
3535// DISASM: bar:
36// DISASM-NEXT: 20004: {{.*}} ret
36// DISASM-NEXT: 210004: {{.*}} ret
3737// DISASM: _start:
38// DISASM-NEXT: 20008: {{.*}} bl #88
39// DISASM-NEXT: 2000c: {{.*}} bl #100
40// DISASM-NEXT: 20010: {{.*}} bl #48
41// DISASM-NEXT: 20014: {{.*}} bl #60
38// DISASM-NEXT: 210008: {{.*}} bl #88
39// DISASM-NEXT: 21000c: {{.*}} bl #100
40// DISASM-NEXT: 210010: {{.*}} bl #48
41// DISASM-NEXT: 210014: {{.*}} bl #60
4242// DISASM-NEXT: Disassembly of section .plt:
4343// DISASM-NEXT: .plt:
44// DISASM-NEXT: 20020: {{.*}} stp x16, x30, [sp, #-16]!
45// DISASM-NEXT: 20024: {{.*}} adrp x16, #65536
46// DISASM-NEXT: 20028: {{.*}} ldr x17, [x16, #16]
47// DISASM-NEXT: 2002c: {{.*}} add x16, x16, #16
48// DISASM-NEXT: 20030: {{.*}} br x17
49// DISASM-NEXT: 20034: {{.*}} nop
50// DISASM-NEXT: 20038: {{.*}} nop
51// DISASM-NEXT: 2003c: {{.*}} nop
52// DISASM-NEXT: 20040: {{.*}} adrp x16, #65536
53// DISASM-NEXT: 20044: {{.*}} ldr x17, [x16, #24]
54// DISASM-NEXT: 20048: {{.*}} add x16, x16, #24
55// DISASM-NEXT: 2004c: {{.*}} br x17
56// DISASM-NEXT: 20050: {{.*}} adrp x16, #65536
57// DISASM-NEXT: 20054: {{.*}} ldr x17, [x16, #32]
58// DISASM-NEXT: 20058: {{.*}} add x16, x16, #32
59// DISASM-NEXT: 2005c: {{.*}} br x17
60// DISASM-NEXT: 20060: {{.*}} adrp x16, #65536
61// DISASM-NEXT: 20064: {{.*}} ldr x17, [x16, #40]
62// DISASM-NEXT: 20068: {{.*}} add x16, x16, #40
63// DISASM-NEXT: 2006c: {{.*}} br x17
64// DISASM-NEXT: 20070: {{.*}} adrp x16, #65536
65// DISASM-NEXT: 20074: {{.*}} ldr x17, [x16, #48]
66// DISASM-NEXT: 20078: {{.*}} add x16, x16, #48
67// DISASM-NEXT: 2007c: {{.*}} br x17
44// DISASM-NEXT: 210020: {{.*}} stp x16, x30, [sp, #-16]!
45// DISASM-NEXT: 210024: {{.*}} adrp x16, #65536
46// DISASM-NEXT: 210028: {{.*}} ldr x17, [x16, #16]
47// DISASM-NEXT: 21002c: {{.*}} add x16, x16, #16
48// DISASM-NEXT: 210030: {{.*}} br x17
49// DISASM-NEXT: 210034: {{.*}} nop
50// DISASM-NEXT: 210038: {{.*}} nop
51// DISASM-NEXT: 21003c: {{.*}} nop
52// DISASM-EMPTY:
53// DISASM-NEXT: bar2@plt:
54// DISASM-NEXT: 210040: {{.*}} adrp x16, #65536
55// DISASM-NEXT: 210044: {{.*}} ldr x17, [x16, #24]
56// DISASM-NEXT: 210048: {{.*}} add x16, x16, #24
57// DISASM-NEXT: 21004c: {{.*}} br x17
58// DISASM-EMPTY:
59// DISASM-NEXT: zed2@plt:
60// DISASM-NEXT: 210050: {{.*}} adrp x16, #65536
61// DISASM-NEXT: 210054: {{.*}} ldr x17, [x16, #32]
62// DISASM-NEXT: 210058: {{.*}} add x16, x16, #32
63// DISASM-NEXT: 21005c: {{.*}} br x17
64// DISASM-NEXT: 210060: {{.*}} adrp x16, #65536
65// DISASM-NEXT: 210064: {{.*}} ldr x17, [x16, #40]
66// DISASM-NEXT: 210068: {{.*}} add x16, x16, #40
67// 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
6973.text
7074.type foo STT_GNU_IFUNC
deps/lld/test/ELF/aarch64-gnu-ifunc.s+23-23
......@@ -16,14 +16,14 @@
1616// CHECK-NEXT: Offset: 0x158
1717// CHECK-NEXT: Size: 48
1818// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
19// CHECK-NEXT: Info: 4
2020// CHECK-NEXT: AddressAlignment: 8
2121// CHECK-NEXT: EntrySize: 24
2222// CHECK-NEXT: }
2323// CHECK: Relocations [
2424// CHECK-NEXT: Section ({{.*}}) .rela.plt {
25// CHECK-NEXT: 0x30000 R_AARCH64_IRELATIVE
26// CHECK-NEXT: 0x30008 R_AARCH64_IRELATIVE
25// CHECK-NEXT: 0x220000 R_AARCH64_IRELATIVE
26// CHECK-NEXT: 0x220008 R_AARCH64_IRELATIVE
2727// CHECK-NEXT: }
2828// CHECK-NEXT: ]
2929// CHECK: Symbols [
......@@ -38,7 +38,7 @@
3838// CHECK-NEXT: }
3939// CHECK-NEXT: Symbol {
4040// CHECK-NEXT: Name: $x.0
41// CHECK-NEXT: Value: 0x20000
41// CHECK-NEXT: Value: 0x210000
4242// CHECK-NEXT: Size: 0
4343// CHECK-NEXT: Binding: Local
4444// CHECK-NEXT: Type: None
......@@ -47,7 +47,7 @@
4747// CHECK-NEXT: }
4848// CHECK-NEXT: Symbol {
4949// CHECK-NEXT: Name: __rela_iplt_end
50// CHECK-NEXT: Value: 0x10188
50// CHECK-NEXT: Value: 0x200188
5151// CHECK-NEXT: Size: 0
5252// CHECK-NEXT: Binding: Local
5353// CHECK-NEXT: Type: None
......@@ -58,7 +58,7 @@
5858// CHECK-NEXT: }
5959// CHECK-NEXT: Symbol {
6060// CHECK-NEXT: Name: __rela_iplt_start
61// CHECK-NEXT: Value: 0x10158
61// CHECK-NEXT: Value: 0x200158
6262// CHECK-NEXT: Size: 0
6363// CHECK-NEXT: Binding: Local
6464// CHECK-NEXT: Type: None
......@@ -69,7 +69,7 @@
6969// CHECK-NEXT: }
7070// CHECK-NEXT: Symbol {
7171// CHECK-NEXT: Name: _start
72// CHECK-NEXT: Value: 0x20008
72// CHECK-NEXT: Value: 0x210008
7373// CHECK-NEXT: Size: 0
7474// CHECK-NEXT: Binding: Global
7575// CHECK-NEXT: Type: None
......@@ -78,7 +78,7 @@
7878// CHECK-NEXT: }
7979// CHECK-NEXT: Symbol {
8080// CHECK-NEXT: Name: bar
81// CHECK-NEXT: Value: 0x20004
81// CHECK-NEXT: Value: 0x210004
8282// CHECK-NEXT: Size: 0
8383// CHECK-NEXT: Binding: Global
8484// CHECK-NEXT: Type: GNU_IFunc
......@@ -87,7 +87,7 @@
8787// CHECK-NEXT: }
8888// CHECK-NEXT: Symbol {
8989// CHECK-NEXT: Name: foo
90// CHECK-NEXT: Value: 0x20000
90// CHECK-NEXT: Value: 0x210000
9191// CHECK-NEXT: Size: 0
9292// CHECK-NEXT: Binding: Global
9393// CHECK-NEXT: Type: GNU_IFunc
......@@ -101,24 +101,24 @@
101101
102102// DISASM: Disassembly of section .text:
103103// DISASM-NEXT: foo:
104// DISASM-NEXT: 20000: c0 03 5f d6 ret
104// DISASM-NEXT: 210000: c0 03 5f d6 ret
105105// DISASM: bar:
106// DISASM-NEXT: 20004: c0 03 5f d6 ret
106// DISASM-NEXT: 210004: c0 03 5f d6 ret
107107// DISASM: _start:
108// DISASM-NEXT: 20008: 06 00 00 94 bl #24
109// DISASM-NEXT: 2000c: 09 00 00 94 bl #36
110// DISASM-NEXT: 20010: 42 60 05 91 add x2, x2, #344
111// DISASM-NEXT: 20014: 42 20 06 91 add x2, x2, #392
108// DISASM-NEXT: 210008: 06 00 00 94 bl #24
109// DISASM-NEXT: 21000c: 09 00 00 94 bl #36
110// DISASM-NEXT: 210010: 42 60 05 91 add x2, x2, #344
111// DISASM-NEXT: 210014: 42 20 06 91 add x2, x2, #392
112112// DISASM-NEXT: Disassembly of section .plt:
113113// DISASM-NEXT: .plt:
114// DISASM-NEXT: 20020: 90 00 00 90 adrp x16, #65536
115// DISASM-NEXT: 20024: 11 02 40 f9 ldr x17, [x16]
116// DISASM-NEXT: 20028: 10 02 00 91 add x16, x16, #0
117// DISASM-NEXT: 2002c: 20 02 1f d6 br x17
118// DISASM-NEXT: 20030: 90 00 00 90 adrp x16, #65536
119// DISASM-NEXT: 20034: 11 06 40 f9 ldr x17, [x16, #8]
120// DISASM-NEXT: 20038: 10 22 00 91 add x16, x16, #8
121// DISASM-NEXT: 2003c: 20 02 1f d6 br x17
114// DISASM-NEXT: 210020: 90 00 00 90 adrp x16, #65536
115// DISASM-NEXT: 210024: 11 02 40 f9 ldr x17, [x16]
116// DISASM-NEXT: 210028: 10 02 00 91 add x16, x16, #0
117// DISASM-NEXT: 21002c: 20 02 1f d6 br x17
118// DISASM-NEXT: 210030: 90 00 00 90 adrp x16, #65536
119// DISASM-NEXT: 210034: 11 06 40 f9 ldr x17, [x16, #8]
120// DISASM-NEXT: 210038: 10 22 00 91 add x16, x16, #8
121// DISASM-NEXT: 21003c: 20 02 1f d6 br x17
122122
123123.text
124124.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:
1111
1212// CHECK: Disassembly of section .text:
1313// CHECK-NEXT: _start:
14// CHECK-NEXT: 20000: 02 00 00 14 b #8
14// CHECK-NEXT: 210000: 02 00 00 14 b #8
1515// CHECK: __AArch64AbsLongThunk_big:
16// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 2000c: 00 02 1f d6 br x16
16// CHECK-NEXT: 210008: 50 00 00 58 ldr x16, #8
17// CHECK-NEXT: 21000c: 00 02 1f d6 br x16
1818// CHECK: $d:
19// CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000
20// CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010
19// CHECK-NEXT: 210010: 00 00 00 00 .word 0x00000000
20// CHECK-NEXT: 210014: 10 00 00 00 .word 0x00000010
deps/lld/test/ELF/aarch64-lo12-alignment.s+4-4
......@@ -39,7 +39,7 @@ foo4:
3939foo8:
4040 .space 8
4141
42// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x30001 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 bytes
44// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x30004 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 bytes
42// 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: 0x220002 is not aligned to 4 bytes
44// 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: 0x220008 is not aligned to 16 bytes
deps/lld/test/ELF/aarch64-prel16.s+12-12
......@@ -7,8 +7,8 @@
77.globl _start
88_start:
99.data
10 .hword foo - . + 0x20eff
11 .hword foo - . + 0x8f02
10 .hword foo - . + 0x210eff
11 .hword foo - . + 0x1f8f02
1212
1313// Note: If this test fails, it probably happens because of
1414// the change of the address of the .data section.
......@@ -18,14 +18,14 @@ _start:
1818// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1919
2020// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x20eff, P = 0x11000
22// S + A - P = 0xffff
23// 11002: S = 0x100, A = 0x8f02, P = 0x11002
24// S + A - P = 0x8000
25// CHECK-NEXT: 11000 ffff0080
21// 201000: S = 0x100, A = 0x210eff, P = 0x201000
22// S + A - P = 0xffff
23// 201002: S = 0x100, A = 0x1f8f02, P = 0x201002
24// S + A - P = 0x8000
25// CHECK-NEXT: 201000 ffff0080
2626
27// RUN: not ld.lld %t.o %t255.o -o %t2
28// | FileCheck %s --check-prefix=OVERFLOW
29// RUN: not ld.lld %t.o %t257.o -o %t2
30// | FileCheck %s --check-prefix=OVERFLOW
31// OVERFLOW: Relocation R_AARCH64_PREL16 out of range: -94209 is not in [-32768, 65535]
27// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
28// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 32767]
29
30// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
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 @@
77.globl _start
88_start:
99.data
10 .word foo - . + 0x100010eff
11 .word foo - . - 0x7ffef0fc
10 .word foo - . + 0x100200eff
11 .word foo - . - 0x7fdff0fc
1212
1313// Note: If this test fails, it probably happens because of
1414// the change of the address of the .data section.
......@@ -18,14 +18,14 @@ _start:
1818// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
1919
2020// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x100010eff, P = 0x11000
22// S + A - P = 0xffffffff
23// 11004: S = 0x100, A = -0x7ffef0fc, P = 0x11004
24// S + A - P = 0x80000000
25// CHECK-NEXT: 11000 ffffffff 00000080
21// 201000: S = 0x100, A = 0x100200eff, P = 0x201000
22// S + A - P = 0xffffffff
23// 201004: S = 0x100, A = -0x7fdff0fc, P = 0x201004
24// S + A - P = 0x80000000
25// CHECK-NEXT: 201000 ffffffff 00000080
2626
27// RUN: not ld.lld %t.o %t255.o -o %t2
28// | FileCheck %s --check-prefix=OVERFLOW
29// RUN: not ld.lld %t.o %t257.o -o %t2
30// | FileCheck %s --check-prefix=OVERFLOW
31// OVERFLOW: Relocation R_AARCH64_PREL32 out of range: 18446744071562006527 is not in [-2147483648, 4294967295]
27// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
28// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 2147483647]
29
30// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
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:
2424 .asciz "blah"
2525 .size mystr, 4
2626
27# S = 0x20012, A = 0x4, P = 0x20012
28# PAGE(S + A) = 0x11000
29# PAGE(P) = 0x11000
27# S = 0x210012, A = 0x4, P = 0x210012
28# PAGE(S + A) = 0x210000
29# PAGE(P) = 0x210000
3030#
3131# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
3232# CHECK-NEXT: $x.2:
33# CHECK-NEXT: 20012: 01 00 00 90 adrp x1, #0
33# CHECK-NEXT: 210012: 01 00 00 90 adrp x1, #0
3434
3535.section .R_AARCH64_ADD_ABS_LO12_NC,"ax",@progbits
3636 add x0, x0, :lo12:.L.str
......@@ -38,13 +38,13 @@ mystr:
3838 .asciz "blah"
3939 .size mystr, 4
4040
41# S = 0x2001b, A = 0x4
41# S = 0x21001b, A = 0x4
4242# R = (S + A) & 0xFFF = 0x1f
4343# R << 10 = 0x7c00
4444#
4545# CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:
4646# CHECK-NEXT: $x.4:
47# CHECK-NEXT: 2001b: 00 7c 00 91 add x0, x0, #31
47# CHECK-NEXT: 21001b: 00 7c 00 91 add x0, x0, #31
4848
4949.section .R_AARCH64_LDST64_ABS_LO12_NC,"ax",@progbits
5050 ldr x28, [x27, :lo12:foo]
......@@ -52,12 +52,12 @@ foo:
5252 .asciz "foo"
5353 .size mystr, 3
5454
55# S = 0x20024, A = 0x4
55# S = 0x210024, A = 0x4
5656# R = ((S + A) & 0xFFF) << 7 = 0x00001400
5757# 0x00001400 | 0xf940177c = 0xf940177c
5858# CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:
5959# 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
6262.section .SUB,"ax",@progbits
6363 nop
......@@ -66,33 +66,33 @@ sub:
6666
6767# CHECK: Disassembly of section .SUB:
6868# CHECK-NEXT: $x.8:
69# CHECK-NEXT: 2002c: 1f 20 03 d5 nop
69# CHECK-NEXT: 21002c: 1f 20 03 d5 nop
7070# CHECK: sub:
71# CHECK-NEXT: 20030: 1f 20 03 d5 nop
71# CHECK-NEXT: 210030: 1f 20 03 d5 nop
7272
7373.section .R_AARCH64_CALL26,"ax",@progbits
7474call26:
7575 bl sub
7676
77# S = 0x2002c, A = 0x4, P = 0x20034
77# S = 0x21002c, A = 0x4, P = 0x210034
7878# R = S + A - P = -0x4 = 0xfffffffc
7979# (R & 0x0ffffffc) >> 2 = 0x03ffffff
8080# 0x94000000 | 0x03ffffff = 0x97ffffff
8181# CHECK: Disassembly of section .R_AARCH64_CALL26:
8282# CHECK-NEXT: call26:
83# CHECK-NEXT: 20034: ff ff ff 97 bl #-4
83# CHECK-NEXT: 210034: ff ff ff 97 bl #-4
8484
8585.section .R_AARCH64_JUMP26,"ax",@progbits
8686jump26:
8787 b sub
8888
89# S = 0x2002c, A = 0x4, P = 0x20038
89# S = 0x21002c, A = 0x4, P = 0x210038
9090# R = S + A - P = -0x8 = 0xfffffff8
9191# (R & 0x0ffffffc) >> 2 = 0x03fffffe
9292# 0x14000000 | 0x03fffffe = 0x17fffffe
9393# CHECK: Disassembly of section .R_AARCH64_JUMP26:
9494# CHECK-NEXT: jump26:
95# CHECK-NEXT: 20038: fe ff ff 17 b #-8
95# CHECK-NEXT: 210038: fe ff ff 17 b #-8
9696
9797.section .R_AARCH64_LDST32_ABS_LO12_NC,"ax",@progbits
9898ldst32:
......@@ -101,12 +101,12 @@ foo32:
101101 .asciz "foo"
102102 .size mystr, 3
103103
104# S = 0x2003c, A = 0x4
104# S = 0x21003c, A = 0x4
105105# R = ((S + A) & 0xFFC) << 8 = 0x00004000
106106# 0x00004000 | 0xbd4000a4 = 0xbd4040a4
107107# CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:
108108# 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
111111.section .R_AARCH64_LDST8_ABS_LO12_NC,"ax",@progbits
112112ldst8:
......@@ -115,12 +115,12 @@ foo8:
115115 .asciz "foo"
116116 .size mystr, 3
117117
118# S = 0x20044, A = 0x4
118# S = 0x210044, A = 0x4
119119# R = ((S + A) & 0xFFF) << 10 = 0x00012000
120120# 0x00012000 | 0x398001ab = 0x398121ab
121121# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
122122# 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
125125.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits
126126ldst128:
......@@ -129,14 +129,14 @@ foo128:
129129 .asciz "foo"
130130 .size mystr, 3
131131
132# S = 0x2004c, A = 0x4
132# S = 0x21004c, A = 0x4
133133# R = ((S + A) & 0xFF8) << 6 = 0x00001400
134134# 0x00001400 | 0x3dc00274 = 0x3dc01674
135135# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
136136# CHECK: ldst128:
137# CHECK: 2004c: 74 16 c0 3d ldr q20, [x19, #80]
137# CHECK: 21004c: 74 16 c0 3d ldr q20, [x19, #80]
138138#foo128:
139# 20050: 66 6f 6f 00 .word
139# 210050: 66 6f 6f 00 .word
140140
141141.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits
142142ldst16:
......@@ -147,14 +147,14 @@ foo16:
147147 .asciz "foo"
148148 .size mystr, 4
149149
150# S = 0x20054, A = 0x4
150# S = 0x210054, A = 0x4
151151# R = ((S + A) & 0x0FFC) << 9 = 0xb000
152152# 0xb000 | 0x7d400271 = 0x7d40b271
153153# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
154154# CHECK-NEXT: ldst16:
155# CHECK-NEXT: 20054: 71 c2 40 7d ldr h17, [x19, #96]
156# CHECK-NEXT: 20058: 61 c2 40 79 ldrh w1, [x19, #96]
157# CHECK-NEXT: 2005c: 62 c6 40 79 ldrh w2, [x19, #98]
155# CHECK-NEXT: 210054: 71 c2 40 7d ldr h17, [x19, #96]
156# CHECK-NEXT: 210058: 61 c2 40 79 ldrh w1, [x19, #96]
157# CHECK-NEXT: 21005c: 62 c6 40 79 ldrh w2, [x19, #98]
158158
159159.section .R_AARCH64_MOVW_UABS,"ax",@progbits
160160movz1:
deps/lld/test/ELF/aarch64-thunk-pi.s+4
......@@ -81,10 +81,14 @@ high_target2:
8181// CHECK-NEXT: 10000034: 1f 20 03 d5 nop
8282// CHECK-NEXT: 10000038: 1f 20 03 d5 nop
8383// CHECK-NEXT: 1000003c: 1f 20 03 d5 nop
84// CHECK-EMPTY:
85// CHECK-NEXT: high_target@plt:
8486// CHECK-NEXT: 10000040: 10 00 00 90 adrp x16, #0
8587// CHECK-NEXT: 10000044: 11 3e 40 f9 ldr x17, [x16, #120]
8688// CHECK-NEXT: 10000048: 10 e2 01 91 add x16, x16, #120
8789// CHECK-NEXT: 1000004c: 20 02 1f d6 br x17
90// CHECK-EMPTY:
91// CHECK-NEXT: low_target@plt:
8892// CHECK-NEXT: 10000050: 10 00 00 90 adrp x16, #0
8993// CHECK-NEXT: 10000054: 11 42 40 f9 ldr x17, [x16, #128]
9094// 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 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
33// 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 %s
4// RUN: llvm-objdump -d -start-address=136118280 -stop-address=136118292 -triple=aarch64-linux-gnu %t2 | FileCheck %s
55// Check that the range extension thunks are dumped close to the aarch64 branch
66// range of 128 MiB
77 .section .text.1, "ax", %progbits
......@@ -35,7 +35,7 @@ high_target:
3535 ret
3636
3737// CHECK: __AArch64AbsLongThunk_high_target:
38// CHECK-NEXT: 7fe0008: 50 00 00 58 ldr x16, #8
39// CHECK-NEXT: 7fe000c: 00 02 1f d6 br x16
38// CHECK-NEXT: 81d0008: 50 00 00 58 ldr x16, #8
39// CHECK-NEXT: 81d000c: 00 02 1f d6 br x16
4040// CHECK: $d:
41// CHECK-NEXT: 7fe0010: 00 10 02 08 .word 0x08021000
41// CHECK-NEXT: 81d0010: 00 10 21 08 .word 0x08211000
deps/lld/test/ELF/aarch64-tls-gdie.s+7-7
......@@ -21,14 +21,14 @@ _start:
2121// SEC-NEXT: SHF_ALLOC
2222// SEC-NEXT: SHF_WRITE
2323// SEC-NEXT: ]
24// SEC-NEXT: Address: 0x300B0
24// SEC-NEXT: Address: 0x2200B0
2525
26// page(0x300B0) - page(0x20004) = 65536
26// page(0x2200B0) - page(0x20004) = 65536
2727// 0x0B0 = 176
2828
2929// CHECK: _start:
30// CHECK-NEXT: 20000: {{.*}} nop
31// CHECK-NEXT: 20004: {{.*}} adrp x0, #65536
32// CHECK-NEXT: 20008: {{.*}} ldr x0, [x0, #176]
33// CHECK-NEXT: 2000c: {{.*}} nop
34// CHECK-NEXT: 20010: {{.*}} nop
30// CHECK-NEXT: 210000: {{.*}} nop
31// CHECK-NEXT: 210004: {{.*}} adrp x0, #65536
32// CHECK-NEXT: 210008: {{.*}} ldr x0, [x0, #176]
33// CHECK-NEXT: 21000c: {{.*}} nop
34// CHECK-NEXT: 210010: {{.*}} nop
deps/lld/test/ELF/aarch64-tls-gdle.s+6-6
......@@ -5,17 +5,17 @@
55# RUN: llvm-objdump -d %tout | FileCheck %s
66# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
77
8#Local-Dynamic to Initial-Exec relax creates no
8#Local-Dynamic to Local-Exec relax creates no
99#RELOC: Relocations [
1010#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.
1313# CHECK: Disassembly of section .text:
1414# CHECK: _start:
15# CHECK: 20000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK: 20004: 00 02 80 f2 movk x0, #16
17# CHECK: 20008: 1f 20 03 d5 nop
18# CHECK: 2000c: 1f 20 03 d5 nop
15# CHECK: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK: 210004: 00 08 80 f2 movk x0, #64
17# CHECK: 210008: 1f 20 03 d5 nop
18# CHECK: 21000c: 1f 20 03 d5 nop
1919
2020.globl _start
2121_start:
deps/lld/test/ELF/aarch64-tls-ie.s+11-11
......@@ -15,7 +15,7 @@
1515#RELOC-NEXT: SHF_ALLOC
1616#RELOC-NEXT: SHF_WRITE
1717#RELOC-NEXT: ]
18#RELOC-NEXT: Address: 0x300B0
18#RELOC-NEXT: Address: 0x2200B0
1919#RELOC-NEXT: Offset: 0x200B0
2020#RELOC-NEXT: Size: 16
2121#RELOC-NEXT: Link: 0
......@@ -25,21 +25,21 @@
2525#RELOC-NEXT: }
2626#RELOC: Relocations [
2727#RELOC-NEXT: Section ({{.*}}) .rela.dyn {
28#RELOC-NEXT: 0x300B8 R_AARCH64_TLS_TPREL64 bar 0x0
29#RELOC-NEXT: 0x300B0 R_AARCH64_TLS_TPREL64 foo 0x0
28#RELOC-NEXT: 0x2200B8 R_AARCH64_TLS_TPREL64 bar 0x0
29#RELOC-NEXT: 0x2200B0 R_AARCH64_TLS_TPREL64 foo 0x0
3030#RELOC-NEXT: }
3131#RELOC-NEXT:]
3232
33# Page(0x300B0) - Page(0x20000) = 0x10000 = 65536
34# 0x300B0 & 0xff8 = 0xB0 = 176
35# Page(0x300B8) - Page(0x20000) = 0x10000 = 65536
36# 0x300B8 & 0xff8 = 0xB8 = 184
33# Page(0x2200B0) - Page(0x210000) = 0x10000 = 65536
34# 0x2200B0 & 0xff8 = 0xB0 = 176
35# Page(0x2200B8) - Page(0x210000) = 0x10000 = 65536
36# 0x2200B8 & 0xff8 = 0xB8 = 184
3737#CHECK: Disassembly of section .text:
3838#CHECK: _start:
39#CHECK: 20000: 80 00 00 90 adrp x0, #65536
40#CHECK: 20004: 00 58 40 f9 ldr x0, [x0, #176]
41#CHECK: 20008: 80 00 00 90 adrp x0, #65536
42#CHECK: 2000c: 00 5c 40 f9 ldr x0, [x0, #184]
39#CHECK: 210000: 80 00 00 90 adrp x0, #65536
40#CHECK: 210004: 00 58 40 f9 ldr x0, [x0, #176]
41#CHECK: 210008: 80 00 00 90 adrp x0, #65536
42#CHECK: 21000c: 00 5c 40 f9 ldr x0, [x0, #184]
4343
4444.globl _start
4545_start:
deps/lld/test/ELF/aarch64-tls-iele.s+5-5
......@@ -9,13 +9,13 @@
99# RELOC: Relocations [
1010# 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.
1313# CHECK: Disassembly of section .text:
1414# CHECK: _start:
15# CHECK-NEXT: 20000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK-NEXT: 20004: 80 02 80 f2 movk x0, #20
17# CHECK-NEXT: 20008: 00 00 a0 d2 movz x0, #0, lsl #16
18# CHECK-NEXT: 2000c: 00 02 80 f2 movk x0, #16
15# CHECK-NEXT: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK-NEXT: 210004: 80 08 80 f2 movk x0, #68
17# CHECK-NEXT: 210008: 00 00 a0 d2 movz x0, #0, lsl #16
18# CHECK-NEXT: 21000c: 00 08 80 f2 movk x0, #64
1919
2020.section .tdata
2121.align 2
deps/lld/test/ELF/aarch64-tls-le.s+23-6
......@@ -4,7 +4,7 @@
44# RUN: llvm-objdump -d %tout | FileCheck %s
55# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
66
7#Local-Dynamic to Initial-Exec relax creates no
7#Local-Dynamic to Local-Exec relax creates no
88#RELOC: Relocations [
99#RELOC-NEXT: ]
1010
......@@ -13,19 +13,36 @@ _start:
1313 mrs x0, TPIDR_EL0
1414 add x0, x0, :tprel_hi12:v1
1515 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.
1821#CHECK: Disassembly of section .text:
1922#CHECK: _start:
20#CHECK: 20000: 40 d0 3b d5 mrs x0, TPIDR_EL0
21#CHECK: 20004: 00 00 40 91 add x0, x0, #0, lsl #12
22#CHECK: 20008: 00 40 00 91 add x0, x0, #16
23#CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0
24#CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12
25#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
2530.section .tbss,"awT",@nobits
31
32.type v1,@object
2633.globl v1
2734.p2align 2
2835v1:
2936.word 0
3037.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
2525 ldrb w0, [x8, :tprel_lo12_nc:var4]
2626
2727// CHECK: _start:
28// CHECK-NEXT: 20000: 48 d0 3b d5 mrs x8, TPIDR_EL0
29// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0
30// CHECK-NEXT: 20004: 08 01 40 91 add x8, x8, #0, lsl #12
31// CHECK-NEXT: 20008: 14 05 c3 3d ldr q20, [x8, #3088]
32// 0x1000 + 0x820 = 0x1820 = tcb + var1
33// CHECK-NEXT: 2000c: 08 05 40 91 add x8, x8, #1, lsl #12
34// CHECK-NEXT: 20010: 00 11 44 f9 ldr x0, [x8, #2080]
35// 0x2000 + 0x428 = 0x2428 = tcb + var2
36// CHECK-NEXT: 20014: 08 09 40 91 add x8, x8, #2, lsl #12
37// CHECK-NEXT: 20018: 00 29 44 b9 ldr w0, [x8, #1064]
38// 0x3000 + 0x2c = 0x302c = tcb + var3
39// CHECK-NEXT: 2001c: 08 0d 40 91 add x8, x8, #3, lsl #12
40// CHECK-NEXT: 20020: 00 59 40 79 ldrh w0, [x8, #44]
41// 0x3000 + 0xc2e = 0x32ce = tcb + var4
42// CHECK-NEXT: 20024: 08 0d 40 91 add x8, x8, #3, lsl #12
43// CHECK-NEXT: 20028: 00 b9 70 39 ldrb w0, [x8, #3118]
28// CHECK-NEXT: 210000: 48 d0 3b d5 mrs x8, TPIDR_EL0
29// 0x0 + c40 = 0xc40 = tcb (64-bytes) + var0
30// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
31// CHECK-NEXT: 210008: 14 11 c3 3d ldr q20, [x8, #3136]
32// 0x1000 + 0x850 = 0x1850 = tcb + var1
33// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
34// CHECK-NEXT: 210010: 00 29 44 f9 ldr x0, [x8, #2128]
35// 0x2000 + 0x458 = 0x2458 = tcb + var2
36// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
37// CHECK-NEXT: 210018: 00 59 44 b9 ldr w0, [x8, #1112]
38// 0x3000 + 0x5c = 0x305c = tcb + var3
39// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
40// CHECK-NEXT: 210020: 00 b9 40 79 ldrh w0, [x8, #92]
41// 0x3000 + 0xc5e = 0x3c5e = tcb + var4
42// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
43// CHECK-NEXT: 210028: 00 79 71 39 ldrb w0, [x8, #3166]
4444
45// CHECK-SYMS: 0000000000000c00 0 TLS GLOBAL DEFAULT 2 var0
46// CHECK-SYMS-NEXT: 0000000000001810 4 TLS GLOBAL DEFAULT 2 var1
47// CHECK-SYMS-NEXT: 0000000000002418 2 TLS GLOBAL DEFAULT 2 var2
48// CHECK-SYMS-NEXT: 000000000000301c 1 TLS GLOBAL DEFAULT 2 var3
49// CHECK-SYMS-NEXT: 0000000000003c1e 0 TLS GLOBAL DEFAULT 2 var4
45// CHECK-SYMS: 0000000000000c00 16 TLS GLOBAL DEFAULT 2 var0
46// CHECK-SYMS-NEXT: 0000000000001810 8 TLS GLOBAL DEFAULT 2 var1
47// CHECK-SYMS-NEXT: 0000000000002418 4 TLS GLOBAL DEFAULT 2 var2
48// CHECK-SYMS-NEXT: 000000000000301c 2 TLS GLOBAL DEFAULT 2 var3
49// CHECK-SYMS-NEXT: 0000000000003c1e 1 TLS GLOBAL DEFAULT 2 var4
5050
5151 .globl var0
5252 .globl var1
......@@ -59,12 +59,12 @@ _start: mrs x8, TPIDR_EL0
5959 .type var3,@object
6060
6161.section .tbss,"awT",@nobits
62 .balign 16
62 .balign 64
6363 .space 1024 * 3
6464var0:
6565 .quad 0
6666 .quad 0
67 .size var1, 16
67 .size var0, 16
6868 .space 1024 * 3
6969var1:
7070 .quad 0
......@@ -72,14 +72,14 @@ var1:
7272 .space 1024 * 3
7373var2:
7474 .word 0
75 .size var1, 4
75 .size var2, 4
7676
7777 .space 1024 * 3
7878var3:
7979 .hword 0
80 .size var2, 2
80 .size var3, 2
8181 .space 1024 * 3
8282var4:
8383 .byte 0
84 .size var3, 1
84 .size var4, 1
8585 .space 1024 * 3
deps/lld/test/ELF/aarch64-tstbr14-reloc.s+15-11
......@@ -13,19 +13,19 @@
1313# 0x11028 - 24 = 0x20010
1414# CHECK: Disassembly of section .text:
1515# CHECK-NEXT: _foo:
16# CHECK-NEXT: 20000: {{.*}} nop
17# CHECK-NEXT: 20004: {{.*}} nop
18# CHECK-NEXT: 20008: {{.*}} nop
19# CHECK-NEXT: 2000c: {{.*}} nop
16# CHECK-NEXT: 210000: {{.*}} nop
17# CHECK-NEXT: 210004: {{.*}} nop
18# CHECK-NEXT: 210008: {{.*}} nop
19# CHECK-NEXT: 21000c: {{.*}} nop
2020# CHECK: _bar:
21# CHECK-NEXT: 20010: {{.*}} nop
22# CHECK-NEXT: 20014: {{.*}} nop
23# CHECK-NEXT: 20018: {{.*}} nop
21# CHECK-NEXT: 210010: {{.*}} nop
22# CHECK-NEXT: 210014: {{.*}} nop
23# CHECK-NEXT: 210018: {{.*}} nop
2424# CHECK: _start:
25# CHECK-NEXT: 2001c: {{.*}} tbnz w3, #15, #-28
26# CHECK-NEXT: 20020: {{.*}} tbnz w3, #15, #-16
27# CHECK-NEXT: 20024: {{.*}} tbz x6, #45, #-36
28# CHECK-NEXT: 20028: {{.*}} tbz x6, #45, #-24
25# CHECK-NEXT: 21001c: {{.*}} tbnz w3, #15, #-28
26# CHECK-NEXT: 210020: {{.*}} tbnz w3, #15, #-16
27# CHECK-NEXT: 210024: {{.*}} tbz x6, #45, #-36
28# CHECK-NEXT: 210028: {{.*}} tbz x6, #45, #-24
2929
3030#DSOREL: Section {
3131#DSOREL: Index:
......@@ -79,10 +79,14 @@
7979#DSO-NEXT: 10044: {{.*}} nop
8080#DSO-NEXT: 10048: {{.*}} nop
8181#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-EMPTY:
83#DSO-NEXT: _foo@plt:
8284#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
8385#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
8486#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
8587#DSO-NEXT: 1005c: {{.*}} br x17
88#DSO-EMPTY:
89#DSO-NEXT: _bar@plt:
8690#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
8791#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
8892#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
deps/lld/test/ELF/aarch64-undefined-weak.s+12-12
......@@ -34,16 +34,16 @@ _start:
3434 ldr x8, target
3535
3636// CHECK: Disassembly of section .text:
37// 131072 = 0x20000
38// CHECK: 20000: {{.*}} b #4
39// CHECK-NEXT: 20004: {{.*}} bl #4
40// CHECK-NEXT: 20008: {{.*}} b.eq #4
41// CHECK-NEXT: 2000c: {{.*}} cbz x1, #4
42// CHECK-NEXT: 20010: {{.*}} adr x0, #0
43// CHECK-NEXT: 20014: {{.*}} adrp x0, #-131072
44// CHECK: 20018: {{.*}} .word 0x00000000
45// CHECK-NEXT: 2001c: {{.*}} .word 0x00000000
46// CHECK-NEXT: 20020: {{.*}} .word 0x00000000
47// CHECK-NEXT: 20024: {{.*}} .short 0x0000
37// 2162688 = 0x210000
38// CHECK: 210000: {{.*}} b #4
39// CHECK-NEXT: 210004: {{.*}} bl #4
40// CHECK-NEXT: 210008: {{.*}} b.eq #4
41// CHECK-NEXT: 21000c: {{.*}} cbz x1, #4
42// CHECK-NEXT: 210010: {{.*}} adr x0, #0
43// CHECK-NEXT: 210014: {{.*}} adrp x0, #0
44// CHECK: 210018: {{.*}} .word 0x00000000
45// CHECK-NEXT: 21001c: {{.*}} .word 0x00000000
46// CHECK-NEXT: 210020: {{.*}} .word 0x00000000
47// CHECK-NEXT: 210024: {{.*}} .short 0x0000
4848// CHECK: $x.2:
49// CHECK-NEXT: 20026: {{.*}} ldr x8, #0
49// CHECK-NEXT: 210026: {{.*}} ldr x8, #0
deps/lld/test/ELF/amdgpu-elf-flags-err.s+2-2
......@@ -1,6 +1,6 @@
11# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx802 -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.o
2# 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 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o
44# RUN: not ld.lld -shared %t-0.o %t-1.o -o /dev/null 2>&1 | FileCheck %s
55
66# CHECK: error: incompatible e_flags: {{.*}}-1.o
deps/lld/test/ELF/amdgpu-elf-flags.s+2-2
......@@ -1,6 +1,6 @@
11# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -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.o
2# 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 -mattr=-code-object-v3 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o
44# RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so
55# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
66
deps/lld/test/ELF/amdgpu-kernels.s+1-1
......@@ -1,5 +1,5 @@
11# REQUIRES: amdgpu
2# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
2# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -mattr=-code-object-v3 %s -o %t.o
33# RUN: ld.lld -shared %t.o -o %t
44# 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
3// 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
59// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
610// extended range encoding is not supported. The following example has a Thumb
711// BL that is out of range on ARM v6 and requires a range extension thunk.
812// 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 a
10// warning for unsupported features.
13// use these instructions either.
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.
1416// ARM v6 supports blx so we shouldn't see the blx not supported warning.
1517// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
1618 .text
1719 .syntax unified
1820 .cpu arm1176jzf-s
19 .eabi_attribute 6, 6 @ Tag_CPU_arch
2021 .globl _start
2122 .type _start,%function
2223 .balign 0x1000
......@@ -24,6 +25,10 @@ _start:
2425 bl thumbfunc
2526 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
2732 .thumb
2833 .section .text.2, "ax", %progbits
2934 .globl thumbfunc
......@@ -31,11 +36,17 @@ _start:
3136thumbfunc:
3237 bl farthumbfunc
3338
34// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6
35// Arm, but not on a v7 Arm.
39// CHECK-THUMB1: thumbfunc:
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
3644 .section .text.3, "ax", %progbits
3745 .space 0x200000
38
46// 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
3950 .section .text.4, "ax", %progbits
4051 .space 0x200000
4152
......@@ -49,3 +60,5 @@ thumbfunc:
4960 .type farthumbfunc,%function
5061farthumbfunc:
5162 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
44
55// On Arm v4t there is no blx instruction so all interworking must go via
66// a thunk. At present we don't support v4t so we give a warning for unsupported
77// features.
88
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.
9// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected
1210
1311 .text
1412 .syntax unified
1513 .cpu arm7tdmi
16 .eabi_attribute 6, 2 @ Tag_CPU_arch
1714 .arm
1815 .globl _start
1916 .type _start,%function
deps/lld/test/ELF/arm-branch-rangethunk.s+3-3
......@@ -1,9 +1,9 @@
11// REQUIRES: arm
2// RUN: llvm-mc -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 %tfar
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
44// RUN: ld.lld %t %tfar -o %t2 2>&1
55// 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 %tfarlong
6// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
77// RUN: ld.lld %t %tfarlong -o %t3 2>&1
88// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s
99 .syntax unified
deps/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
33// RUN: ld.lld %t --shared -o %t.so
4// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
4// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
55// RUN: ld.lld %t2 %t.so -o %t3
66// 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:
3535// CHECK-NEXT: Address: 0x100F4
3636// CHECK-NEXT: Offset: 0xF4
3737// CHECK-NEXT: Size: 16
38// CHECK-NEXT: Link:
39// CHECK-NEXT: Info: 4
3840// CHECK: Name: .plt
3941// CHECK-NEXT: Type: SHT_PROGBITS
4042// CHECK-NEXT: Flags [
......@@ -44,7 +46,8 @@ _start:
4446// CHECK-NEXT: Address: 0x11020
4547// CHECK-NEXT: Offset: 0x1020
4648// CHECK-NEXT: Size: 32
47// CHECK: Name: .got
49// CHECK: Index: 4
50// CHECK-NEXT: Name: .got
4851// CHECK-NEXT: Type: SHT_PROGBITS
4952// CHECK-NEXT: Flags [
5053// CHECK-NEXT: SHF_ALLOC
deps/lld/test/ELF/arm-long-thunk-converge.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s
2// RUN: llvm-mc -triple armv7-unknown-gnu -arm-add-build-attributes -filetype=obj -o %t %s
33// RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2
44// RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -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 %tfar
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
44// RUN: ld.lld %t %tfar -o %t2 2>&1
55// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2
66 .syntax unified
deps/lld/test/ELF/arm-thumb-branch.s+2-2
......@@ -1,6 +1,6 @@
11// REQUIRES: arm
2// RUN: llvm-mc -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 %tfar
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
3// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
44// RUN: echo "SECTIONS { \
55// RUN: . = 0xb4; \
66// RUN: .callee1 : { *(.callee_low) } \
deps/lld/test/ELF/arm-thumb-condbranch-thunk.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t --shared -o %t.so
44// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld %t.o -o /dev/null -image-base=0x80000000
44
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: . = SIZEOF_HEADERS; \
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t --shared --icf=all -o %t.so
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: echo "SECTIONS { \
44// RUN: .text_armfunc 0x1000 : { *(.text_armfunc) } \
55// RUN: .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \
deps/lld/test/ELF/arm-thunk-largesection.s+7-4
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s
55// 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:
1616 bx lr
1717 .space 0x1000
1818// CHECK1: Disassembly of section .text:
19// CHECK1-NEXT: _start:
20// CHECK1-NEXT: 11000: 70 47 bx lr
21// CHECK1-NEXT: 11002: 00 00 movs r0, r0
19// CHECK1-NEXT:_start:
20// CHECK1-NEXT: 11000: 70 47 bx lr
21// CHECK1-EMPTY:
22// CHECK-NEXT:$d.1:
23// CHECK-NEXT: 11002: 00 00 .short 0x0000
24
2225
2326// CHECK2: __Thumbv7ABSLongThunk__start:
2427// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: . = SIZEOF_HEADERS; \
55// 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 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: .text 0x100000 : { *(.text) } \
55// RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \
......@@ -21,7 +21,8 @@
2121// per OutputSection basis
2222 .syntax unified
2323
24// Define a function that we can match with .text_l* aligned on a megabyte // boundary
24// Define a function that we can match with .text_l* aligned on a megabyte
25// boundary
2526 .macro FUNCTIONL suff
2627 .section .text_l\suff\(), "ax", %progbits
2728 .thumb
deps/lld/test/ELF/arm-thunk-linkerscript-orphan.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: .text_low 0x100000 : { *(.text_low) } \
55// RUN: .text_high 0x2000000 : { *(.text_high) } \
deps/lld/test/ELF/arm-thunk-linkerscript-sort.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \
55// RUN: }" > %t.script
deps/lld/test/ELF/arm-thunk-linkerscript.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: echo "SECTIONS { \
44// RUN: . = SIZEOF_HEADERS; \
55// RUN: .text_low : { *(.text_low) *(.text_low2) } \
deps/lld/test/ELF/arm-thunk-multipass.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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// REQUIRES: ARM
1// REQUIRES: arm
22// RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7a-linux-gnueabihf --filetype=obj -o %t.o
33// RUN: ld.lld %t.o -o %t
44// RUN: llvm-objdump -triple=thumbv7a-linux-gnueabihf -d -start-address=2166784 -stop-address=2166794 %t | FileCheck %s
......@@ -23,8 +23,7 @@ _start:
2323// CHECK-NEXT: 211000: 00 f0 00 80 beq.w #0
2424// CHECK: __Thumbv7ABSLongThunk_target:
2525// CHECK-NEXT: 211004: 00 f0 01 90 b.w #12582914
26// CHECK: $t.1:
27// CHECK-NEXT: 211008: 70 47 bx lr
26// CHECK: 211008: 70 47 bx lr
2827
2928 .section .text.2, "ax", %progbits
3029 .space 12 * 1024 * 1024
deps/lld/test/ELF/arm-thunk-re-add.s+1-1
......@@ -1,5 +1,5 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t --shared -o %t.so
44// The output file is large, most of it zeroes. We dissassemble only the
55// 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// REQUIRES: ARM
1// REQUIRES: arm
22// RUN: llvm-mc %s -triple=armv7a-linux-gnueabihf -arm-add-build-attributes -filetype=obj -o %t.o
33// 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:
6969
7070// CHECK: Disassembly of section .text:
7171// CHECK-NEXT: _start:
72// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
73// CHECK-NEXT: 11000: 08 00 00 00
74// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
75// CHECK-NEXT: 11004: 10 00 00 00
76// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
77// CHECK-NEXT: 11008: 0c 00 00 00
72// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20)
73// CHECK-NEXT: 11000: 20 00 00 00
74// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28)
75// CHECK-NEXT: 11004: 28 00 00 00
76// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24)
77// CHECK-NEXT: 11008: 24 00 00 00
deps/lld/test/ELF/arm-tls-norelax-ie-le.s+2-2
......@@ -37,5 +37,5 @@ x2:
3737 .type x2, %object
3838
3939// CHECK: Contents of section .got:
40// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8
41// CHECK-NEXT: 13064 08000000 0c000000
40// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
41// 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 @@
1212
1313# CHECK: Symbol table of .hash for image:
1414# 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
1717.globl _start
1818.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:
5959# CHECK-NEXT: SHF_ALLOC (0x2)
6060# CHECK-NEXT: SHF_EXECINSTR (0x4)
6161# CHECK-NEXT: ]
62# CHECK-NEXT: Address: 0x20000
62# CHECK-NEXT: Address: 0x210000
6363# CHECK-NEXT: Offset: 0x10000
6464# CHECK-NEXT: Size: 12
6565# CHECK-NEXT: Link: 0
......@@ -138,7 +138,7 @@ _start:
138138# CHECK-NEXT: }
139139# CHECK-NEXT: Symbol {
140140# CHECK-NEXT: Name: $x.0
141# CHECK-NEXT: Value: 0x20000
141# CHECK-NEXT: Value: 0x210000
142142# CHECK-NEXT: Size: 0
143143# CHECK-NEXT: Binding: Local (0x0)
144144# CHECK-NEXT: Type: None (0x0)
......@@ -159,8 +159,8 @@ _start:
159159# CHECK-NEXT: ProgramHeader {
160160# CHECK-NEXT: Type: PT_PHDR (0x6)
161161# CHECK-NEXT: Offset: 0x40
162# CHECK-NEXT: VirtualAddress: 0x10040
163# CHECK-NEXT: PhysicalAddress: 0x10040
162# CHECK-NEXT: VirtualAddress: 0x200040
163# CHECK-NEXT: PhysicalAddress: 0x200040
164164# CHECK-NEXT: FileSize: 224
165165# CHECK-NEXT: MemSize: 224
166166# CHECK-NEXT: Flags [ (0x4)
......@@ -171,8 +171,8 @@ _start:
171171# CHECK-NEXT: ProgramHeader {
172172# CHECK-NEXT: Type: PT_LOAD (0x1)
173173# CHECK-NEXT: Offset: 0x0
174# CHECK-NEXT: VirtualAddress: 0x10000
175# CHECK-NEXT: PhysicalAddress: 0x10000
174# CHECK-NEXT: VirtualAddress: 0x200000
175# CHECK-NEXT: PhysicalAddress: 0x200000
176176# CHECK-NEXT: FileSize: 288
177177# CHECK-NEXT: MemSize: 288
178178# CHECK-NEXT: Flags [
......@@ -183,8 +183,8 @@ _start:
183183# CHECK-NEXT: ProgramHeader {
184184# CHECK-NEXT: Type: PT_LOAD (0x1)
185185# CHECK-NEXT: Offset: 0x1000
186# CHECK-NEXT: VirtualAddress: 0x20000
187# CHECK-NEXT: PhysicalAddress: 0x20000
186# CHECK-NEXT: VirtualAddress: 0x210000
187# CHECK-NEXT: PhysicalAddress: 0x210000
188188# CHECK-NEXT: FileSize: 4096
189189# CHECK-NEXT: MemSize: 4096
190190# CHECK-NEXT: Flags [ (0x5)
deps/lld/test/ELF/basic-ppc64.s+34-17
......@@ -28,7 +28,7 @@
2828// CHECK-NEXT: Version: 1
2929// CHECK-NEXT: Entry: 0x10000
3030// CHECK-NEXT: ProgramHeaderOffset: 0x40
31// CHECK-NEXT: SectionHeaderOffset:
31// CHECK-NEXT: SectionHeaderOffset: 0x200F8
3232// CHECK-NEXT: Flags [ (0x2)
3333// CHECK-NEXT: 0x2
3434// CHECK-NEXT: ]
......@@ -36,8 +36,8 @@
3636// CHECK-NEXT: ProgramHeaderEntrySize: 56
3737// CHECK-NEXT: ProgramHeaderCount: 7
3838// CHECK-NEXT: SectionHeaderEntrySize: 64
39// CHECK-NEXT: SectionHeaderCount: 10
40// CHECK-NEXT: StringTableSectionIndex: 8
39// CHECK-NEXT: SectionHeaderCount: 11
40// CHECK-NEXT: StringTableSectionIndex: 9
4141// CHECK-NEXT:}
4242// CHECK-NEXT:Sections [
4343// CHECK-NEXT: Section {
......@@ -156,7 +156,23 @@
156156// CHECK-NEXT: }
157157// CHECK-NEXT: Section {
158158// 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)
160176// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
161177// CHECK-NEXT: Flags [ (0x30)
162178// CHECK-NEXT: SHF_MERGE (0x10)
......@@ -174,15 +190,15 @@
174190// CHECK-NEXT: )
175191// CHECK-NEXT: }
176192// CHECK-NEXT: Section {
177// CHECK-NEXT: Index: 7
178// CHECK-NEXT: Name: .symtab (47)
193// CHECK-NEXT: Index: 8
194// CHECK-NEXT: Name: .symtab (58)
179195// CHECK-NEXT: Type: SHT_SYMTAB (0x2)
180196// CHECK-NEXT: Flags [ (0x0)
181197// CHECK-NEXT: ]
182198// CHECK-NEXT: Address: 0x0
183199// CHECK-NEXT: Offset: 0x20068
184200// CHECK-NEXT: Size: 48
185// CHECK-NEXT: Link: 9
201// CHECK-NEXT: Link: 10
186202// CHECK-NEXT: Info: 2
187203// CHECK-NEXT: AddressAlignment: 8
188204// CHECK-NEXT: EntrySize: 24
......@@ -193,14 +209,14 @@
193209// CHECK-NEXT: )
194210// CHECK-NEXT: }
195211// CHECK-NEXT: Section {
196// CHECK-NEXT: Index: 8
197// CHECK-NEXT: Name: .shstrtab (55)
212// CHECK-NEXT: Index: 9
213// CHECK-NEXT: Name: .shstrtab (66)
198214// CHECK-NEXT: Type: SHT_STRTAB (0x3)
199215// CHECK-NEXT: Flags [ (0x0)
200216// CHECK-NEXT: ]
201217// CHECK-NEXT: Address: 0x0
202218// CHECK-NEXT: Offset: 0x20098
203// CHECK-NEXT: Size: 73
219// CHECK-NEXT: Size: 84
204220// CHECK-NEXT: Link: 0
205221// CHECK-NEXT: Info: 0
206222// CHECK-NEXT: AddressAlignment: 1
......@@ -208,19 +224,20 @@
208224// CHECK-NEXT: SectionData (
209225// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|
210226// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|
211// CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..|
212// CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab|
213// CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.|
227// CHECK-NEXT: 0020: 6E616D69 63002E62 72616E63 685F6C74 |namic..branch_lt|
228// CHECK-NEXT: 0030: 002E636F 6D6D656E 74002E73 796D7461 |..comment..symta|
229// CHECK-NEXT: 0040: 62002E73 68737472 74616200 2E737472 |b..shstrtab..str|
230// CHECK-NEXT: 0050: 74616200 |tab.|
214231// CHECK-NEXT: )
215232// CHECK-NEXT: }
216233// CHECK-NEXT: Section {
217// CHECK-NEXT: Index: 9
218// CHECK-NEXT: Name: .strtab (65)
234// CHECK-NEXT: Index: 10
235// CHECK-NEXT: Name: .strtab (76)
219236// CHECK-NEXT: Type: SHT_STRTAB (0x3)
220237// CHECK-NEXT: Flags [ (0x0)
221238// CHECK-NEXT: ]
222239// CHECK-NEXT: Address: 0x0
223// CHECK-NEXT: Offset: 0x200E1
240// CHECK-NEXT: Offset: 0x200EC
224241// CHECK-NEXT: Size: 10
225242// CHECK-NEXT: Link: 0
226243// CHECK-NEXT: Info: 0
......@@ -275,7 +292,7 @@
275292// CHECK-NEXT: VirtualAddress: 0x20000
276293// CHECK-NEXT: PhysicalAddress: 0x20000
277294// CHECK-NEXT: FileSize: 96
278// CHECK-NEXT: MemSize: 96
295// CHECK-NEXT: MemSize: 65536
279296// CHECK-NEXT: Flags [ (0x6)
280297// CHECK-NEXT: PF_R (0x4)
281298// CHECK-NEXT: PF_W (0x2)
deps/lld/test/ELF/basic32.s+8-8
......@@ -23,7 +23,7 @@ _start:
2323# CHECK-NEXT: Type: Executable (0x2)
2424# CHECK-NEXT: Machine: EM_386 (0x3)
2525# CHECK-NEXT: Version: 1
26# CHECK-NEXT: Entry: 0x11000
26# CHECK-NEXT: Entry: 0x401000
2727# CHECK-NEXT: ProgramHeaderOffset: 0x34
2828# CHECK-NEXT: SectionHeaderOffset: 0x205C
2929# CHECK-NEXT: Flags [ (0x0)
......@@ -58,7 +58,7 @@ _start:
5858# CHECK-NEXT: SHF_ALLOC (0x2)
5959# CHECK-NEXT: SHF_EXECINSTR (0x4)
6060# CHECK-NEXT: ]
61# CHECK-NEXT: Address: 0x11000
61# CHECK-NEXT: Address: 0x401000
6262# CHECK-NEXT: Offset: 0x1000
6363# CHECK-NEXT: Size: 12
6464# CHECK-NEXT: Link: 0
......@@ -129,8 +129,8 @@ _start:
129129# CHECK-NEXT: ProgramHeader {
130130# CHECK-NEXT: Type: PT_PHDR (0x6)
131131# CHECK-NEXT: Offset: 0x34
132# CHECK-NEXT: VirtualAddress: 0x10034
133# CHECK-NEXT: PhysicalAddress: 0x10034
132# CHECK-NEXT: VirtualAddress: 0x400034
133# CHECK-NEXT: PhysicalAddress: 0x400034
134134# CHECK-NEXT: FileSize: 128
135135# CHECK-NEXT: MemSize: 128
136136# CHECK-NEXT: Flags [ (0x4)
......@@ -141,8 +141,8 @@ _start:
141141# CHECK-NEXT: ProgramHeader {
142142# CHECK-NEXT: Type: PT_LOAD (0x1)
143143# CHECK-NEXT: Offset: 0x0
144# CHECK-NEXT: VirtualAddress: 0x10000
145# CHECK-NEXT: PhysicalAddress: 0x10000
144# CHECK-NEXT: VirtualAddress: 0x400000
145# CHECK-NEXT: PhysicalAddress: 0x400000
146146# CHECK-NEXT: FileSize: 180
147147# CHECK-NEXT: MemSize: 180
148148# CHECK-NEXT: Flags [
......@@ -153,8 +153,8 @@ _start:
153153# CHECK-NEXT: ProgramHeader {
154154# CHECK-NEXT: Type: PT_LOAD (0x1)
155155# CHECK-NEXT: Offset: 0x1000
156# CHECK-NEXT: VirtualAddress: 0x11000
157# CHECK-NEXT: PhysicalAddress: 0x11000
156# CHECK-NEXT: VirtualAddress: 0x401000
157# CHECK-NEXT: PhysicalAddress: 0x401000
158158# CHECK-NEXT: FileSize: 4096
159159# CHECK-NEXT: MemSize: 4096
160160# CHECK-NEXT: Flags [ (0x5)
deps/lld/test/ELF/basic64be.s+42-23
......@@ -23,7 +23,7 @@
2323# CHECK-NEXT: Version: 1
2424# CHECK-NEXT: Entry: 0x10010000
2525# CHECK-NEXT: ProgramHeaderOffset: 0x40
26# CHECK-NEXT: SectionHeaderOffset: 0x11050
26# CHECK-NEXT: SectionHeaderOffset: 0x20058
2727# CHECK-NEXT: Flags [ (0x2)
2828# CHECK-NEXT: 0x2
2929# CHECK-NEXT: ]
......@@ -31,8 +31,8 @@
3131# CHECK-NEXT: ProgramHeaderEntrySize: 56
3232# CHECK-NEXT: ProgramHeaderCount: 4
3333# CHECK-NEXT: SectionHeaderEntrySize: 64
34# CHECK-NEXT: SectionHeaderCount: 6
35# CHECK-NEXT: StringTableSectionIndex: 4
34# CHECK-NEXT: SectionHeaderCount: 7
35# CHECK-NEXT: StringTableSectionIndex: 5
3636# CHECK-NEXT: }
3737# CHECK-NEXT: Sections [
3838# CHECK-NEXT: Section {
......@@ -72,14 +72,32 @@
7272# CHECK-NEXT: }
7373# CHECK-NEXT: Section {
7474# 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)
7694# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
7795# CHECK-NEXT: Flags [ (0x30)
7896# CHECK-NEXT: SHF_MERGE (0x10)
7997# CHECK-NEXT: SHF_STRINGS (0x20)
8098# CHECK-NEXT: ]
8199# CHECK-NEXT: Address: 0x0
82# CHECK-NEXT: Offset: 0x11000
100# CHECK-NEXT: Offset: 0x20000
83101# CHECK-NEXT: Size: 8
84102# CHECK-NEXT: Link: 0
85103# CHECK-NEXT: Info: 0
......@@ -90,15 +108,15 @@
90108# CHECK-NEXT: )
91109# CHECK-NEXT: }
92110# CHECK-NEXT: Section {
93# CHECK-NEXT: Index: 3
94# CHECK-NEXT: Name: .symtab (16)
111# CHECK-NEXT: Index: 4
112# CHECK-NEXT: Name: .symtab (27)
95113# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
96114# CHECK-NEXT: Flags [ (0x0)
97115# CHECK-NEXT: ]
98116# CHECK-NEXT: Address: 0x0
99# CHECK-NEXT: Offset: 0x11008
117# CHECK-NEXT: Offset: 0x20008
100118# CHECK-NEXT: Size: 24
101# CHECK-NEXT: Link: 5
119# CHECK-NEXT: Link: 6
102120# CHECK-NEXT: Info: 1
103121# CHECK-NEXT: AddressAlignment: 8
104122# CHECK-NEXT: EntrySize: 24
......@@ -108,32 +126,33 @@
108126# CHECK-NEXT: )
109127# CHECK-NEXT: }
110128# CHECK-NEXT: Section {
111# CHECK-NEXT: Index: 4
112# CHECK-NEXT: Name: .shstrtab (24)
129# CHECK-NEXT: Index: 5
130# CHECK-NEXT: Name: .shstrtab (35)
113131# CHECK-NEXT: Type: SHT_STRTAB (0x3)
114132# CHECK-NEXT: Flags [ (0x0)
115133# CHECK-NEXT: ]
116134# CHECK-NEXT: Address: 0x0
117# CHECK-NEXT: Offset: 0x11020
118# CHECK-NEXT: Size: 42
135# CHECK-NEXT: Offset: 0x20020
136# CHECK-NEXT: Size: 53
119137# CHECK-NEXT: Link: 0
120138# CHECK-NEXT: Info: 0
121139# CHECK-NEXT: AddressAlignment: 1
122140# CHECK-NEXT: EntrySize: 0
123141# CHECK-NEXT: SectionData (
124# CHECK-NEXT: 0000: 002E7465 7874002E 636F6D6D 656E7400 |..text..comment.|
125# CHECK-NEXT: 0010: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta|
126# CHECK-NEXT: 0020: 62002E73 74727461 6200 |b..strtab.|
142# CHECK-NEXT: 0000: 002E7465 7874002E 6272616E 63685F6C |..text..branch_l|
143# CHECK-NEXT: 0010: 74002E63 6F6D6D65 6E74002E 73796D74 |t..comment..symt|
144# CHECK-NEXT: 0020: 6162002E 73687374 72746162 002E7374 |ab..shstrtab..st|
145# CHECK-NEXT: 0030: 72746162 00 |rtab.|
127146# CHECK-NEXT: )
128147# CHECK-NEXT: }
129148# CHECK-NEXT: Section {
130# CHECK-NEXT: Index: 5
131# CHECK-NEXT: Name: .strtab (34)
149# CHECK-NEXT: Index: 6
150# CHECK-NEXT: Name: .strtab (45)
132151# CHECK-NEXT: Type: SHT_STRTAB (0x3)
133152# CHECK-NEXT: Flags [ (0x0)
134153# CHECK-NEXT: ]
135154# CHECK-NEXT: Address: 0x0
136# CHECK-NEXT: Offset: 0x1104A
155# CHECK-NEXT: Offset: 0x20055
137156# CHECK-NEXT: Size: 1
138157# CHECK-NEXT: Link: 0
139158# CHECK-NEXT: Info: 0
......@@ -150,8 +169,8 @@
150169# CHECK-NEXT: Offset: 0x40
151170# CHECK-NEXT: VirtualAddress: 0x10000040
152171# CHECK-NEXT: PhysicalAddress: 0x10000040
153# CHECK-NEXT: FileSize: 224
154# CHECK-NEXT: MemSize: 224
172# CHECK-NEXT: FileSize: 280
173# CHECK-NEXT: MemSize: 280
155174# CHECK-NEXT: Flags [ (0x4)
156175# CHECK-NEXT: PF_R (0x4)
157176# CHECK-NEXT: ]
......@@ -162,8 +181,8 @@
162181# CHECK-NEXT: Offset: 0x0
163182# CHECK-NEXT: VirtualAddress: 0x10000000
164183# CHECK-NEXT: PhysicalAddress: 0x10000000
165# CHECK-NEXT: FileSize: 288
166# CHECK-NEXT: MemSize: 288
184# CHECK-NEXT: FileSize: 344
185# CHECK-NEXT: MemSize: 344
167186# CHECK-NEXT: Flags [ (0x4)
168187# CHECK-NEXT: PF_R (0x4)
169188# CHECK-NEXT: ]
deps/lld/test/ELF/bsymbolic-undef.s+2-2
......@@ -5,7 +5,7 @@
55
66# CHECK: DynamicSymbols [
77# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @
8# CHECK-NEXT: Name:
99# CHECK-NEXT: Value: 0x0
1010# CHECK-NEXT: Size: 0
1111# CHECK-NEXT: Binding: Local (0x0)
......@@ -14,7 +14,7 @@
1414# CHECK-NEXT: Section: Undefined (0x0)
1515# CHECK-NEXT: }
1616# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: undef@
17# CHECK-NEXT: Name: undef
1818# CHECK-NEXT: Value: 0x0
1919# CHECK-NEXT: Size: 0
2020# 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 @@
44// RUN: ld.lld -shared %t.o %t2.o -o %t
55// RUN: ld.lld -shared %t2.o %t.o -o %t
66
7.section .gnu.linkonce.t.zed
7.section .gnu.linkonce.t.__x86.get_pc_thunk.bx
88.globl abc
99abc:
1010nop
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 @@
33# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
44# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
55
6# CHECK: Name: bar@
7# CHECK: Name: foo@
6# CHECK: Name: bar
7# CHECK: Name: foo
88
99.comm foo,4,4
1010.comm bar,4,4
deps/lld/test/ELF/compressed-debug-input-err.s+2-2
......@@ -3,8 +3,8 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# 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.
7# CHECK: error: {{.*}}.o:(.zdebug_str): decompress failed: zlib error: Z_DATA_ERROR
6## Check we are able to report zlib uncompress errors.
7# CHECK: error: {{.*}}.o:(.debug_str): uncompress failed: zlib error: Z_DATA_ERROR
88
99.section .zdebug_str,"MS",@progbits,1
1010 .ascii "ZLIB"
deps/lld/test/ELF/conflict.s+1
......@@ -26,6 +26,7 @@
2626# RUN: FileCheck -check-prefix=DEMANGLE %s
2727
2828# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o
29# RUN: rm -f %t3.a
2930# RUN: llvm-ar rcs %t3.a %t2.o
3031# 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 @@
99# RUN: llvm-readobj -t -s %t2 | FileCheck %s
1010# 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
1218# CHECK: Symbol {
1319# CHECK: Name: foo1
1420# CHECK-NEXT: Value: 0x123
......@@ -68,8 +74,17 @@
6874# EXPR-NEXT: Section: Absolute
6975# EXPR-NEXT: }
7076
71# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR
72# ERR: error: -defsym:1: symbol not found: und
77# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR1
78# 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
7489.globl foo1
7590 foo1 = 0x123
deps/lld/test/ELF/dont-export-hidden.s+1-1
......@@ -19,7 +19,7 @@ foo:
1919
2020// CHECK: DynamicSymbols [
2121// CHECK-NEXT: Symbol {
22// CHECK-NEXT: Name: @
22// CHECK-NEXT: Name:
2323// CHECK-NEXT: Value: 0x0
2424// CHECK-NEXT: Size: 0
2525// CHECK-NEXT: Binding: Local
deps/lld/test/ELF/driver-access.test+1-1
......@@ -1,4 +1,4 @@
1# REQUIRES: x86, shell
1# REQUIRES: x86
22# Make sure that LLD works even if the current directory is not writable.
33
44# 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 @@
6262# RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s
6363# 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
6568# RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s
6669# ERR11: unknown -z value: max-page-size
6770
deps/lld/test/ELF/dt_flags.s+3-2
......@@ -3,7 +3,8 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# 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 %t1
6# 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
78# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
89
910# RUN: ld.lld %t %t.so -o %t2
......@@ -14,7 +15,7 @@
1415
1516# FLAGS: DynamicSection [
1617# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
17# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE INITFIRST NOOPEN ORIGIN
18# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL NODELETE INITFIRST NOOPEN ORIGIN INTERPOSE NODEFLIB
1819# FLAGS: ]
1920
2021# 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 @@
1616
1717# DYNSYMS: DynamicSymbols [
1818# DYNSYMS-NEXT: Symbol {
19# DYNSYMS-NEXT: Name: @ (0)
19# DYNSYMS-NEXT: Name:
2020# DYNSYMS-NEXT: Value: 0x0
2121# DYNSYMS-NEXT: Size: 0
2222# DYNSYMS-NEXT: Binding: Local
......@@ -25,7 +25,7 @@
2525# DYNSYMS-NEXT: Section: Undefined
2626# DYNSYMS-NEXT: }
2727# DYNSYMS-NEXT: Symbol {
28# DYNSYMS-NEXT: Name: bar@
28# DYNSYMS-NEXT: Name: bar
2929# DYNSYMS-NEXT: Value:
3030# DYNSYMS-NEXT: Size:
3131# DYNSYMS-NEXT: Binding: Global
......@@ -34,7 +34,7 @@
3434# DYNSYMS-NEXT: Section:
3535# DYNSYMS-NEXT: }
3636# DYNSYMS-NEXT: Symbol {
37# DYNSYMS-NEXT: Name: ext@
37# DYNSYMS-NEXT: Name: ext
3838# DYNSYMS-NEXT: Value:
3939# DYNSYMS-NEXT: Size:
4040# DYNSYMS-NEXT: Binding: Global
......@@ -43,7 +43,7 @@
4343# DYNSYMS-NEXT: Section:
4444# DYNSYMS-NEXT: }
4545# DYNSYMS-NEXT: Symbol {
46# DYNSYMS-NEXT: Name: foo@
46# DYNSYMS-NEXT: Name: foo
4747# DYNSYMS-NEXT: Value:
4848# DYNSYMS-NEXT: Size:
4949# 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 @@
88
99# CHECK: DynamicSymbols [
1010# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name: @ (0)
11# CHECK-NEXT: Name:
1212# CHECK-NEXT: Value: 0x0
1313# CHECK-NEXT: Size: 0
1414# CHECK-NEXT: Binding: Local (0x0)
......@@ -17,7 +17,7 @@
1717# CHECK-NEXT: Section: Undefined (0x0)
1818# CHECK-NEXT: }
1919# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: foo1@ (1)
20# CHECK-NEXT: Name: foo1
2121# CHECK-NEXT: Value: 0x1000
2222# CHECK-NEXT: Size: 0
2323# CHECK-NEXT: Binding: Global (0x1)
......@@ -26,7 +26,7 @@
2626# CHECK-NEXT: Section: .text (0x4)
2727# CHECK-NEXT: }
2828# CHECK-NEXT: Symbol {
29# CHECK-NEXT: Name: foo11@ (6)
29# CHECK-NEXT: Name: foo11
3030# CHECK-NEXT: Value: 0x1001
3131# CHECK-NEXT: Size: 0
3232# CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/dynamic-list.s+11-11
......@@ -23,7 +23,7 @@
2323
2424# CHECK: DynamicSymbols [
2525# CHECK-NEXT: Symbol {
26# CHECK-NEXT: Name: @
26# CHECK-NEXT: Name:
2727# CHECK-NEXT: Value: 0x0
2828# CHECK-NEXT: Size: 0
2929# CHECK-NEXT: Binding: Local
......@@ -32,7 +32,7 @@
3232# CHECK-NEXT: Section: Undefined
3333# CHECK-NEXT: }
3434# CHECK-NEXT: Symbol {
35# CHECK-NEXT: Name: foo1@
35# CHECK-NEXT: Name: foo1
3636# CHECK-NEXT: Value: 0x201000
3737# CHECK-NEXT: Size: 0
3838# CHECK-NEXT: Binding: Global (0x1)
......@@ -54,7 +54,7 @@
5454
5555# CHECK2: DynamicSymbols [
5656# CHECK2-NEXT: Symbol {
57# CHECK2-NEXT: Name: @
57# CHECK2-NEXT: Name:
5858# CHECK2-NEXT: Value: 0x0
5959# CHECK2-NEXT: Size: 0
6060# CHECK2-NEXT: Binding: Local
......@@ -63,7 +63,7 @@
6363# CHECK2-NEXT: Section: Undefined
6464# CHECK2-NEXT: }
6565# CHECK2-NEXT: Symbol {
66# CHECK2-NEXT: Name: foo1@
66# CHECK2-NEXT: Name: foo1
6767# CHECK2-NEXT: Value: 0x201000
6868# CHECK2-NEXT: Size: 0
6969# CHECK2-NEXT: Binding: Global (0x1)
......@@ -72,7 +72,7 @@
7272# CHECK2-NEXT: Section: .text (0x4)
7373# CHECK2-NEXT: }
7474# CHECK2-NEXT: Symbol {
75# CHECK2-NEXT: Name: foo2@
75# CHECK2-NEXT: Name: foo2
7676# CHECK2-NEXT: Value: 0x201001
7777# CHECK2-NEXT: Size: 0
7878# CHECK2-NEXT: Binding: Global (0x1)
......@@ -81,7 +81,7 @@
8181# CHECK2-NEXT: Section: .text (0x4)
8282# CHECK2-NEXT: }
8383# CHECK2-NEXT: Symbol {
84# CHECK2-NEXT: Name: foo31@
84# CHECK2-NEXT: Name: foo31
8585# CHECK2-NEXT: Value: 0x201002
8686# CHECK2-NEXT: Size: 0
8787# CHECK2-NEXT: Binding: Global (0x1)
......@@ -104,7 +104,7 @@
104104
105105# CHECK3: DynamicSymbols [
106106# CHECK3-NEXT: Symbol {
107# CHECK3-NEXT: Name: @
107# CHECK3-NEXT: Name:
108108# CHECK3-NEXT: Value: 0x0
109109# CHECK3-NEXT: Size: 0
110110# CHECK3-NEXT: Binding: Local
......@@ -113,7 +113,7 @@
113113# CHECK3-NEXT: Section: Undefined
114114# CHECK3-NEXT: }
115115# CHECK3-NEXT: Symbol {
116# CHECK3-NEXT: Name: _start@
116# CHECK3-NEXT: Name: _start
117117# CHECK3-NEXT: Value: 0x201003
118118# CHECK3-NEXT: Size: 0
119119# CHECK3-NEXT: Binding: Global (0x1)
......@@ -122,7 +122,7 @@
122122# CHECK3-NEXT: Section: .text (0x4)
123123# CHECK3-NEXT: }
124124# CHECK3-NEXT: Symbol {
125# CHECK3-NEXT: Name: foo1@
125# CHECK3-NEXT: Name: foo1
126126# CHECK3-NEXT: Value: 0x201000
127127# CHECK3-NEXT: Size: 0
128128# CHECK3-NEXT: Binding: Global (0x1)
......@@ -131,7 +131,7 @@
131131# CHECK3-NEXT: Section: .text (0x4)
132132# CHECK3-NEXT: }
133133# CHECK3-NEXT: Symbol {
134# CHECK3-NEXT: Name: foo2@
134# CHECK3-NEXT: Name: foo2
135135# CHECK3-NEXT: Value: 0x201001
136136# CHECK3-NEXT: Size: 0
137137# CHECK3-NEXT: Binding: Global (0x1)
......@@ -140,7 +140,7 @@
140140# CHECK3-NEXT: Section: .text (0x4)
141141# CHECK3-NEXT: }
142142# CHECK3-NEXT: Symbol {
143# CHECK3-NEXT: Name: foo31@
143# CHECK3-NEXT: Name: foo31
144144# CHECK3-NEXT: Value: 0x201002
145145# CHECK3-NEXT: Size: 0
146146# CHECK3-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/dynamic-reloc.s+1-1
......@@ -18,7 +18,7 @@
1818// CHECK-NEXT: Offset:
1919// CHECK-NEXT: Size: [[RELASIZE:.*]]
2020// CHECK-NEXT: Link: 1
21// CHECK-NEXT: Info: 0
21// CHECK-NEXT: Info: 7
2222// CHECK-NEXT: AddressAlignment: 8
2323// CHECK-NEXT: EntrySize: 24
2424
deps/lld/test/ELF/dynsym-no-rosegment.s+2-2
......@@ -5,7 +5,7 @@
55
66# CHECK: DynamicSymbols [
77# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @ (0)
8# CHECK-NEXT: Name:
99# CHECK-NEXT: Value: 0x0
1010# CHECK-NEXT: Size: 0
1111# CHECK-NEXT: Binding: Local
......@@ -14,7 +14,7 @@
1414# CHECK-NEXT: Section: Undefined
1515# CHECK-NEXT: }
1616# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: undef@
17# CHECK-NEXT: Name: undef
1818# CHECK-NEXT: Value: 0x0
1919# CHECK-NEXT: Size: 0
2020# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/dynsym-pie.s+1-1
......@@ -50,7 +50,7 @@
5050
5151# CHECK: DynamicSymbols [
5252# CHECK-NEXT: Symbol {
53# CHECK-NEXT: Name: @
53# CHECK-NEXT: Name:
5454# CHECK-NEXT: Value: 0x0
5555# CHECK-NEXT: Size: 0
5656# CHECK-NEXT: Binding: Local
deps/lld/test/ELF/edata-etext.s-1
......@@ -18,7 +18,6 @@
1818# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA
1919# CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS
2020# CHECK: SYMBOL TABLE:
21# CHECK-NEXT: 0000000000000000 *UND* 00000000
2221# CHECK-NEXT: 0000000000202002 .data 00000000 _edata
2322# CHECK-NEXT: 000000000020200a .bss 00000000 _end
2423# 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 @@
2929// CHECK-NEXT: Symbols [
3030// CHECK-NEXT: Symbol {
3131// CHECK-NEXT: Version: 0
32// CHECK-NEXT: Name: @
32// CHECK-NEXT: Name:
3333// CHECK-NEXT: }
3434// CHECK-NEXT: Symbol {
3535// CHECK-NEXT: Version: 2
deps/lld/test/ELF/empty-ver2.s+2-2
......@@ -8,11 +8,11 @@
88# CHECK: Symbols [
99# CHECK-NEXT: Symbol {
1010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @
11# CHECK-NEXT: Name:
1212# CHECK-NEXT: }
1313# CHECK-NEXT: Symbol {
1414# CHECK-NEXT: Version: 1
15# CHECK-NEXT: Name: bar@@
15# CHECK-NEXT: Name: bar@
1616# CHECK-NEXT: }
1717# 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 @@
1616// RUN: }" > %t.lds
1717// 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 code
19// CHECK: cannot place {{.*}}:(.rodata.foo) into .text: -execute-only does not support intermingling data and code
2020
2121 br lr
2222
deps/lld/test/ELF/format-binary.test+12
......@@ -55,3 +55,15 @@
5555# CHECK-NEXT: Other: 0
5656# CHECK-NEXT: Section: Absolute
5757# 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 @@
1212# CHECK-NEXT: SHF_MERGE
1313# CHECK-NEXT: SHF_STRINGS
1414# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x100B4
15# CHECK-NEXT: Address: 0x4000B4
1616
17# 0x100B4 == 65716
18# DISASM: leal 65716, %eax
17# 0x4000B4 == 4194484
18# DISASM: leal 4194484, %eax
1919
2020 .section .foo,"aMS",@progbits,1
2121 .byte 0
deps/lld/test/ELF/gc-sections-linker-defined-symbol.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: ld.lld %t.o -o %t.so --gc-sections -shared
55# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
66
7# CHECK: Name: _end@
7# CHECK: Name: _end
88# CHECK-NEXT: Value:
99# CHECK-NEXT: Size:
1010# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/gdb-index-base-addr.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: ld.lld --gdb-index %t1.o -o %t
44# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
55
6# CHECK: .gnu_index contents:
6# CHECK: .gdb_index contents:
77# CHECK: Address area offset = 0x28, has 2 entries:
88# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
99# 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 @@
33# RUN: ld.lld --gdb-index -e main %t.o -o %t
44# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
55
6# CHECK: .gnu_index contents:
6# CHECK: .gdb_index contents:
77# CHECK: Address area offset = 0x28, has 2 entries:
88# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
99# 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 @@
2525# DISASM-CHECK: 201004: 90 nop
2626# DISASM-CHECK: 201005: 90 nop
2727
28# DWARF: .gnu_index contents:
28# DWARF: .gdb_index contents:
2929# DWARF-NEXT: Version = 7
3030# DWARF: CU list offset = 0x18, has 2 entries:
3131# 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 @@
1313
1414# CHECK: Symbol table '.dynsym' contains 4 entries:
1515# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
16# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @
17# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo@
18# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar@
19# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed@
16# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
17# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo
18# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar
19# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed
2020
2121# CHECK: First Hashed Symbol Index: 2
2222
deps/lld/test/ELF/gnu-hash-table-rwsegment.s+2-2
......@@ -8,8 +8,8 @@
88# CHECK-NEXT: Num Buckets: 1
99# CHECK-NEXT: First Hashed Symbol Index: 1
1010# CHECK-NEXT: Num Mask Words: 1
11# CHECK-NEXT: Shift Count: 6
12# CHECK-NEXT: Bloom Filter: [0x400000000004204]
11# CHECK-NEXT: Shift Count: 26
12# CHECK-NEXT: Bloom Filter: [0x400000000000204]
1313# CHECK-NEXT: Buckets: [1]
1414# CHECK-NEXT: Values: [0xB8860BA, 0xB887389]
1515# CHECK-NEXT: }
deps/lld/test/ELF/gnu-hash-table.s+27-27
......@@ -13,7 +13,7 @@
1313# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o
1414# 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.a
16# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a %t2-ppc64le.a
1717# RUN: llvm-ar rc %t2-i386.a %t2-i386.o
1818# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o
1919# RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o
......@@ -49,7 +49,7 @@
4949
5050# EMPTY: DynamicSymbols [
5151# EMPTY: Symbol {
52# EMPTY: Name: foo@
52# EMPTY: Name: foo
5353# EMPTY-NEXT: Value: 0x0
5454# EMPTY-NEXT: Size: 0
5555# EMPTY-NEXT: Binding: Global
......@@ -62,7 +62,7 @@
6262# EMPTY-NEXT: Num Buckets: 1
6363# EMPTY-NEXT: First Hashed Symbol Index: 2
6464# EMPTY-NEXT: Num Mask Words: 1
65# EMPTY-NEXT: Shift Count: 6
65# EMPTY-NEXT: Shift Count: 26
6666# EMPTY-NEXT: Bloom Filter: [0x0]
6767# EMPTY-NEXT: Buckets: [0]
6868# EMPTY-NEXT: Values: []
......@@ -87,32 +87,32 @@
8787# I386: ]
8888# I386: DynamicSymbols [
8989# I386: Symbol {
90# I386: Name: @
90# I386: Name:
9191# I386: Binding: Local
9292# I386: Section: Undefined
9393# I386: }
9494# I386: Symbol {
95# I386: Name: baz@
95# I386: Name: baz
9696# I386: Binding: Global
9797# I386: Section: Undefined
9898# I386: }
9999# I386: Symbol {
100# I386: Name: xyz@
100# I386: Name: xyz
101101# I386: Binding: Global
102102# I386: Section: Undefined
103103# I386: }
104104# I386: Symbol {
105# I386: Name: zed@
105# I386: Name: zed
106106# I386: Binding: Weak
107107# I386: Section: Undefined
108108# I386: }
109109# I386: Symbol {
110# I386: Name: bar@
110# I386: Name: bar
111111# I386: Binding: Global
112112# I386: Section: .text
113113# I386: }
114114# I386: Symbol {
115# I386: Name: foo@
115# I386: Name: foo
116116# I386: Binding: Global
117117# I386: Section: .text
118118# I386: }
......@@ -121,8 +121,8 @@
121121# I386-NEXT: Num Buckets: 1
122122# I386-NEXT: First Hashed Symbol Index: 4
123123# I386-NEXT: Num Mask Words: 1
124# I386-NEXT: Shift Count: 6
125# I386-NEXT: Bloom Filter: [0x4004204]
124# I386-NEXT: Shift Count: 26
125# I386-NEXT: Bloom Filter: [0x4000204]
126126# I386-NEXT: Buckets: [4]
127127# I386-NEXT: Values: [0xB8860BA, 0xB887389]
128128# I386-NEXT: }
......@@ -147,32 +147,32 @@
147147# X86_64: ]
148148# X86_64: DynamicSymbols [
149149# X86_64: Symbol {
150# X86_64: Name: @
150# X86_64: Name:
151151# X86_64: Binding: Local
152152# X86_64: Section: Undefined
153153# X86_64: }
154154# X86_64: Symbol {
155# X86_64: Name: baz@
155# X86_64: Name: baz
156156# X86_64: Binding: Global
157157# X86_64: Section: Undefined
158158# X86_64: }
159159# X86_64: Symbol {
160# X86_64: Name: xyz@
160# X86_64: Name: xyz
161161# X86_64: Binding: Global
162162# X86_64: Section: Undefined
163163# X86_64: }
164164# X86_64: Symbol {
165# X86_64: Name: zed@
165# X86_64: Name: zed
166166# X86_64: Binding: Weak
167167# X86_64: Section: Undefined
168168# X86_64: }
169169# X86_64: Symbol {
170# X86_64: Name: bar@
170# X86_64: Name: bar
171171# X86_64: Binding: Global
172172# X86_64: Section: .text
173173# X86_64: }
174174# X86_64: Symbol {
175# X86_64: Name: foo@
175# X86_64: Name: foo
176176# X86_64: Binding: Global
177177# X86_64: Section: .text
178178# X86_64: }
......@@ -181,8 +181,8 @@
181181# X86_64-NEXT: Num Buckets: 1
182182# X86_64-NEXT: First Hashed Symbol Index: 4
183183# X86_64-NEXT: Num Mask Words: 1
184# X86_64-NEXT: Shift Count: 6
185# X86_64-NEXT: Bloom Filter: [0x400000000004204]
184# X86_64-NEXT: Shift Count: 26
185# X86_64-NEXT: Bloom Filter: [0x400000000000204]
186186# X86_64-NEXT: Buckets: [4]
187187# X86_64-NEXT: Values: [0xB8860BA, 0xB887389]
188188# X86_64-NEXT: }
......@@ -207,32 +207,32 @@
207207# PPC64: ]
208208# PPC64: DynamicSymbols [
209209# PPC64: Symbol {
210# PPC64: Name: @
210# PPC64: Name:
211211# PPC64: Binding: Local
212212# PPC64: Section: Undefined
213213# PPC64: }
214214# PPC64: Symbol {
215# PPC64: Name: baz@
215# PPC64: Name: baz
216216# PPC64: Binding: Global
217217# PPC64: Section: Undefined
218218# PPC64: }
219219# PPC64: Symbol {
220# PPC64: Name: xyz@
220# PPC64: Name: xyz
221221# PPC64: Binding: Global
222222# PPC64: Section: Undefined
223223# PPC64: }
224224# PPC64: Symbol {
225# PPC64: Name: zed@
225# PPC64: Name: zed
226226# PPC64: Binding: Weak
227227# PPC64: Section: Undefined
228228# PPC64: }
229229# PPC64: Symbol {
230# PPC64: Name: bar@
230# PPC64: Name: bar
231231# PPC64: Binding: Global
232232# PPC64: Section: .text
233233# PPC64: }
234234# PPC64: Symbol {
235# PPC64: Name: foo@
235# PPC64: Name: foo
236236# PPC64: Binding: Global
237237# PPC64: Section: .text
238238# PPC64: }
......@@ -241,8 +241,8 @@
241241# PPC64-NEXT: Num Buckets: 1
242242# PPC64-NEXT: First Hashed Symbol Index: 4
243243# PPC64-NEXT: Num Mask Words: 1
244# PPC64-NEXT: Shift Count: 6
245# PPC64-NEXT: Bloom Filter: [0x400000000004204]
244# PPC64-NEXT: Shift Count: 26
245# PPC64-NEXT: Bloom Filter: [0x400000000000204]
246246# PPC64-NEXT: Buckets: [4]
247247# PPC64-NEXT: Values: [0xB8860BA, 0xB887389]
248248# 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 @@
1616// CHECK-NEXT: Offset: 0xD4
1717// CHECK-NEXT: Size: 16
1818// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
19// CHECK-NEXT: Info: 4
2020// CHECK-NEXT: AddressAlignment: 4
2121// CHECK-NEXT: EntrySize: 8
2222// CHECK-NEXT: }
2323// CHECK: Relocations [
2424// CHECK-NEXT: Section ({{.*}}) .rel.plt {
25// CHECK-NEXT: 0x12000 R_386_IRELATIVE
26// CHECK-NEXT: 0x12004 R_386_IRELATIVE
25// CHECK-NEXT: 0x402000 R_386_IRELATIVE
26// CHECK-NEXT: 0x402004 R_386_IRELATIVE
2727// CHECK-NEXT: }
2828// CHECK-NEXT: ]
2929
......@@ -39,7 +39,7 @@
3939// CHECK-NEXT: }
4040// CHECK-NEXT: Symbol {
4141// CHECK-NEXT: Name: __rel_iplt_end
42// CHECK-NEXT: Value: 0x100E4
42// CHECK-NEXT: Value: 0x4000E4
4343// CHECK-NEXT: Size: 0
4444// CHECK-NEXT: Binding: Local
4545// CHECK-NEXT: Type: None
......@@ -61,7 +61,7 @@
6161// CHECK-NEXT: }
6262// CHECK-NEXT: Symbol {
6363// CHECK-NEXT: Name: _start
64// CHECK-NEXT: Value: 0x11002
64// CHECK-NEXT: Value: 0x401002
6565// CHECK-NEXT: Size: 0
6666// CHECK-NEXT: Binding: Global
6767// CHECK-NEXT: Type: None
......@@ -70,7 +70,7 @@
7070// CHECK-NEXT: }
7171// CHECK-NEXT: Symbol {
7272// CHECK-NEXT: Name: bar
73// CHECK-NEXT: Value: 0x11001
73// CHECK-NEXT: Value: 0x401001
7474// CHECK-NEXT: Size: 0
7575// CHECK-NEXT: Binding: Global
7676// CHECK-NEXT: Type: GNU_IFunc
......@@ -79,7 +79,7 @@
7979// CHECK-NEXT: }
8080// CHECK-NEXT: Symbol {
8181// CHECK-NEXT: Name: foo
82// CHECK-NEXT: Value: 0x11000
82// CHECK-NEXT: Value: 0x401000
8383// CHECK-NEXT: Size: 0
8484// CHECK-NEXT: Binding: Global
8585// CHECK-NEXT: Type: GNU_IFunc
......@@ -90,22 +90,22 @@
9090
9191// DISASM: Disassembly of section .text:
9292// DISASM-NEXT: foo:
93// DISASM-NEXT: 11000: c3 retl
93// DISASM-NEXT: 401000: c3 retl
9494// DISASM: bar:
95// DISASM-NEXT: 11001: c3 retl
95// DISASM-NEXT: 401001: c3 retl
9696// DISASM: _start:
97// DISASM-NEXT: 11002: e8 19 00 00 00 calll 25
98// DISASM-NEXT: 11007: e8 24 00 00 00 calll 36
99// DISASM-NEXT: 1100c: ba d4 00 01 00 movl $65748, %edx
100// DISASM-NEXT: 11011: ba e4 00 01 00 movl $65764, %edx
97// DISASM-NEXT: 401002: e8 19 00 00 00 calll 25
98// DISASM-NEXT: 401007: e8 24 00 00 00 calll 36
99// DISASM-NEXT: 40100c: ba d4 00 40 00 movl $4194516, %edx
100// DISASM-NEXT: 401011: ba e4 00 40 00 movl $4194532, %edx
101101// DISASM-NEXT: Disassembly of section .plt:
102102// DISASM-NEXT: .plt:
103// DISASM-NEXT: 11020: ff 25 00 20 01 00 jmpl *73728
104// DISASM-NEXT: 11026: 68 10 00 00 00 pushl $16
105// DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
106// DISASM-NEXT: 11030: ff 25 04 20 01 00 jmpl *73732
107// DISASM-NEXT: 11036: 68 18 00 00 00 pushl $24
108// DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
103// DISASM-NEXT: 401020: ff 25 00 20 40 00 jmpl *4202496
104// DISASM-NEXT: 401026: 68 10 00 00 00 pushl $16
105// DISASM-NEXT: 40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
106// DISASM-NEXT: 401030: ff 25 04 20 40 00 jmpl *4202500
107// DISASM-NEXT: 401036: 68 18 00 00 00 pushl $24
108// DISASM-NEXT: 40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
109109
110110.text
111111.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-plt-i386.s+34-30
......@@ -10,16 +10,16 @@
1010// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
1111// CHECK: Relocations [
1212// CHECK-NEXT: Section (4) .rel.plt {
13// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar2
14// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed2
15// CHECK-NEXT: 0x12014 R_386_IRELATIVE
16// CHECK-NEXT: 0x12018 R_386_IRELATIVE
13// CHECK-NEXT: 0x40200C R_386_JUMP_SLOT bar2
14// CHECK-NEXT: 0x402010 R_386_JUMP_SLOT zed2
15// CHECK-NEXT: 0x402014 R_386_IRELATIVE
16// CHECK-NEXT: 0x402018 R_386_IRELATIVE
1717
1818// Check that IRELATIVE .got.plt entries point to ifunc resolver and not
1919// back to the plt entry + 6.
2020// GOTPLT: Contents of section .got.plt:
21// GOTPLT: 12000 00300100 00000000 00000000 36100100
22// GOTPLT-NEXT: 12010 46100100 00100100 01100100
21// GOTPLT: 402000 00304000 00000000 00000000 36104000
22// GOTPLT-NEXT: 402010 46104000 00104000 01104000
2323
2424// Check that the PLTRELSZ tag includes the IRELATIVE relocations
2525// CHECK: DynamicSection [
......@@ -28,34 +28,38 @@
2828// Check that a PLT header is written and the ifunc entries appear last
2929// DISASM: Disassembly of section .text:
3030// DISASM-NEXT: foo:
31// DISASM-NEXT: 11000: c3 retl
31// DISASM-NEXT: 401000: c3 retl
3232// DISASM: bar:
33// DISASM-NEXT: 11001: c3 retl
33// DISASM-NEXT: 401001: c3 retl
3434// DISASM: _start:
35// DISASM-NEXT: 11002: e8 49 00 00 00 calll 73
36// DISASM-NEXT: 11007: e8 54 00 00 00 calll 84
37// DISASM-NEXT: 1100c: e8 1f 00 00 00 calll 31
38// DISASM-NEXT: 11011: e8 2a 00 00 00 calll 42
35// DISASM-NEXT: 401002: e8 49 00 00 00 calll 73
36// DISASM-NEXT: 401007: e8 54 00 00 00 calll 84
37// DISASM-NEXT: 40100c: e8 1f 00 00 00 calll 31
38// DISASM-NEXT: 401011: e8 2a 00 00 00 calll 42
3939// DISASM-NEXT: Disassembly of section .plt:
4040// DISASM-NEXT: .plt:
41// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 73732
42// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *73736
43// DISASM-NEXT: 1102c: 90 nop
44// DISASM-NEXT: 1102d: 90 nop
45// DISASM-NEXT: 1102e: 90 nop
46// DISASM-NEXT: 1102f: 90 nop
47// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *73740
48// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $0
49// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>
50// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *73744
51// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $8
52// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>
53// DISASM-NEXT: 11050: ff 25 14 20 01 00 jmpl *73748
54// DISASM-NEXT: 11056: 68 30 00 00 00 pushl $48
55// DISASM-NEXT: 1105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
56// DISASM-NEXT: 11060: ff 25 18 20 01 00 jmpl *73752
57// DISASM-NEXT: 11066: 68 38 00 00 00 pushl $56
58// DISASM-NEXT: 1106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>
41// DISASM-NEXT: 401020: ff 35 04 20 40 00 pushl 4202500
42// DISASM-NEXT: 401026: ff 25 08 20 40 00 jmpl *4202504
43// DISASM-NEXT: 40102c: 90 nop
44// DISASM-NEXT: 40102d: 90 nop
45// DISASM-NEXT: 40102e: 90 nop
46// DISASM-NEXT: 40102f: 90 nop
47// DISASM-EMPTY:
48// DISASM-NEXT: bar2@plt:
49// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
50// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
51// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.plt>
52// DISASM-EMPTY:
53// DISASM-NEXT: zed2@plt:
54// DISASM-NEXT: 401040: ff 25 10 20 40 00 jmpl *4202512
55// DISASM-NEXT: 401046: 68 08 00 00 00 pushl $8
56// DISASM-NEXT: 40104b: e9 d0 ff ff ff jmp -48 <.plt>
57// DISASM-NEXT: 401050: ff 25 14 20 40 00 jmpl *4202516
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
6064.text
6165.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-plt.s+6-2
......@@ -42,18 +42,22 @@
4242// DISASM-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
4343// DISASM-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
4444// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
45// DISASM-EMPTY:
46// DISASM-NEXT: bar2@plt:
4547// DISASM-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
4648// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $0
4749// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
50// DISASM-EMPTY:
51// DISASM-NEXT: zed2@plt:
4852// DISASM-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
4953// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $1
5054// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
5155// DISASM-NEXT: 201050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
5256// 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>
5458// DISASM-NEXT: 201060: ff 25 ca 0f 00 00 jmpq *4042(%rip)
5559// 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
5862.text
5963.type foo STT_GNU_IFUNC
deps/lld/test/ELF/gnu-ifunc-relative.s+9-7
......@@ -1,7 +1,9 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -static %t.o -o %tout
4// RUN: llvm-readobj -r -t %tout | FileCheck %s
3// RUN: ld.lld --strip-all %t.o -o %t
4// 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
68.type foo STT_GNU_IFUNC
79.globl foo
......@@ -16,8 +18,8 @@ _start:
1618// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]
1719// CHECK-NEXT: }
1820
19// CHECK: Name: foo
20// CHECK-NEXT: Value: 0x[[ADDR]]
21// CHECK-NEXT: Size: 0
22// CHECK-NEXT: Binding: Global
23// CHECK-NEXT: Type: GNU_IFunc
21// SYM: Name: foo
22// SYM-NEXT: Value: 0x[[ADDR]]
23// SYM-NEXT: Size: 0
24// SYM-NEXT: Binding: Global
25// SYM-NEXT: Type: GNU_IFunc
deps/lld/test/ELF/gnu-ifunc-shared.s+5-1
......@@ -23,15 +23,19 @@
2323// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
2424// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
2525// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
26// DISASM-EMPTY:
27// DISASM-NEXT: fct2@plt:
2628// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
2729// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
2830// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
31// DISASM-EMPTY:
32// DISASM-NEXT: f2@plt:
2933// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
3034// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
3135// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
3236// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
3337// 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
3640// CHECK: Relocations [
3741// CHECK-NEXT: Section (4) .rela.plt {
deps/lld/test/ELF/gnu-ifunc.s+3-1
......@@ -16,10 +16,12 @@
1616// CHECK-NEXT: Offset: 0x158
1717// CHECK-NEXT: Size: 48
1818// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
19// CHECK-NEXT: Info: [[GOTPLT:.*]]
2020// CHECK-NEXT: AddressAlignment: 8
2121// CHECK-NEXT: EntrySize: 24
2222// CHECK-NEXT: }
23// CHECK: Index: [[GOTPLT]]
24// CHECK-NEXT: Name: .got.plt
2325// CHECK: Relocations [
2426// CHECK-NEXT: Section ({{.*}}) .rela.plt {
2527// CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE
deps/lld/test/ELF/gnu-unique.s+2-2
......@@ -20,7 +20,7 @@ _start:
2020.type symb, @gnu_unique_object
2121symb:
2222
23# GNU: Name: symb@
23# GNU: Name: symb
2424# GNU-NEXT: Value:
2525# GNU-NEXT: Size: 0
2626# GNU-NEXT: Binding: Unique
......@@ -29,7 +29,7 @@ symb:
2929# GNU-NEXT: Section: .data
3030# GNU-NEXT: }
3131
32# NO: Name: symb@
32# NO: Name: symb
3333# NO-NEXT: Value:
3434# NO-NEXT: Size: 0
3535# NO-NEXT: Binding: Global
deps/lld/test/ELF/got-i386.s+9-9
......@@ -10,7 +10,7 @@
1010// CHECK-NEXT: SHF_ALLOC
1111// CHECK-NEXT: SHF_WRITE
1212// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x12000
13// CHECK-NEXT: Address: 0x402000
1414// CHECK-NEXT: Offset:
1515// CHECK-NEXT: Size: 0
1616// CHECK-NEXT: Link:
......@@ -19,7 +19,7 @@
1919
2020// CHECK: Symbol {
2121// CHECK: Name: bar
22// CHECK-NEXT: Value: 0x12000
22// CHECK-NEXT: Value: 0x402000
2323// CHECK-NEXT: Size: 10
2424// CHECK-NEXT: Binding: Global
2525// CHECK-NEXT: Type: Object
......@@ -28,7 +28,7 @@
2828// CHECK-NEXT: }
2929// CHECK-NEXT: Symbol {
3030// CHECK-NEXT: Name: obj
31// CHECK-NEXT: Value: 0x1200A
31// CHECK-NEXT: Value: 0x40200A
3232// CHECK-NEXT: Size: 10
3333// CHECK-NEXT: Binding: Global
3434// CHECK-NEXT: Type: Object
......@@ -36,14 +36,14 @@
3636// CHECK-NEXT: Section: .bss
3737// CHECK-NEXT: }
3838
39// 0x12000 - 0 = addr(.got) = 0x12000
40// 0x1200A - 10 = addr(.got) = 0x12000
41// 0x1200A + 5 - 15 = addr(.got) = 0x12000
39// 0x402000 - 0 = addr(.got) = 0x402000
40// 0x40200A - 10 = addr(.got) = 0x402000
41// 0x40200A + 5 - 15 = addr(.got) = 0x402000
4242// DISASM: Disassembly of section .text:
4343// DISASM-NEXT: _start:
44// DISASM-NEXT: 11000: 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)
46// DISASM-NEXT: 11014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
44// DISASM-NEXT: 401000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)
45// DISASM-NEXT: 40100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)
46// DISASM-NEXT: 401014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
4747
4848.global _start
4949_start:
deps/lld/test/ELF/got32-i386-pie-rw.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readelf -r -s %t | FileCheck %s
4# RUN: llvm-readelf -r -S %t | FileCheck %s
55
66# Unlike bfd and gold we accept this.
77
deps/lld/test/ELF/got32-i386.s+2-2
......@@ -14,10 +14,10 @@ _start:
1414
1515## 73728 == 0x12000 == ADDR(.got)
1616# CHECK: _start:
17# CHECK-NEXT: 11001: 8b 1d {{.*}} movl 73728, %ebx
17# CHECK-NEXT: 401001: 8b 1d {{.*}} movl 4202496, %ebx
1818# CHECK: Sections:
1919# CHECK: Name Size Address
20# CHECK: .got 00000004 0000000000012000
20# CHECK: .got 00000004 0000000000402000
2121
2222# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
2323# 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 @@
3333
3434## 73728 == 0x12000 == ADDR(.got)
3535# CHECK: _start:
36# CHECK-NEXT: 11001: 8b 05 {{.*}} movl 77824, %eax
37# CHECK-NEXT: 11007: 8b 1d {{.*}} movl 77824, %ebx
38# CHECK-NEXT: 1100d: 8b 80 {{.*}} movl -4(%eax), %eax
39# CHECK-NEXT: 11013: 8b 83 {{.*}} movl -4(%ebx), %eax
36# CHECK-NEXT: 401001: 8b 05 {{.*}} movl 4206592, %eax
37# CHECK-NEXT: 401007: 8b 1d {{.*}} movl 4206592, %ebx
38# CHECK-NEXT: 40100d: 8b 80 {{.*}} movl -4(%eax), %eax
39# CHECK-NEXT: 401013: 8b 83 {{.*}} movl -4(%ebx), %eax
4040# CHECK: Sections:
4141# CHECK: Name Size Address
42# CHECK: .got 00000004 0000000000013000
42# CHECK: .got 00000004 0000000000403000
4343
4444# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
4545# 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 @@
44# RUN: ld.lld %t2 %t -o %t3
55# RUN: llvm-objdump -d %t3 | FileCheck %s
66
7# Note: 69632 == 0x11000
7# Note: 131072 == 0x20000
88# R_HEX_32_6_X
99# R_HEX_12_X
1010if (p0) r0 = ##_start
11# CHECK: immext(#69632)
12# CHECK: if (p0) r0 = ##69632
11# CHECK: immext(#131072)
12# CHECK: if (p0) r0 = ##131072
1313
1414# R_HEX_B15_PCREL
1515if (p0) jump:nt #_start
16# CHECK: if (p0) jump:nt 0x11000
16# CHECK: if (p0) jump:nt 0x20000
1717
1818# R_HEX_B32_PCREL_X
1919# R_HEX_B15_PCREL_X
2020if (p0) jump:nt ##_start
21# CHECK: if (p0) jump:nt 0x11000
21# CHECK: if (p0) jump:nt 0x20000
2222
2323# R_HEX_B22_PCREL
2424call #_start
25# CHECK: call 0x11000
25# CHECK: call 0x20000
2626
2727# R_HEX_B32_PCREL_X
2828# R_HEX_B22_PCREL_X
2929call ##_start
3030# CHECK: immext(#4294967232)
31# CHECK: call 0x11000
31# 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 @@
44# RUN: ld.lld %t1.o -o %t.out
55# RUN: llvm-objdump -s -t %t.out | FileCheck %s
66# CHECK: Contents of section .text:
7# CHECK-NEXT: 11000 020000
8## 0x11003 - 0x11000 + addend(-1) = 0x02
9## 0x11003 - 0x11001 + addend(-2) = 0x0000
7# CHECK-NEXT: 401000 020000
8## 0x401003 - 0x401000 + addend(-1) = 0x02
9## 0x401003 - 0x401001 + addend(-2) = 0x0000
1010# CHECK: SYMBOL TABLE:
11# CHECK: 00011003 .und
11# CHECK: 00401003 .und
1212
1313.byte und-.-1
1414.short und-.-2
deps/lld/test/ELF/i386-retpoline-nopic.s+48-48
......@@ -8,56 +8,56 @@
88
99// CHECK: Disassembly of section .plt:
1010// CHECK-NEXT: .plt:
11// CHECK-NEXT: 11010: ff 35 04 20 01 00 pushl 73732
12// CHECK-NEXT: 11016: 50 pushl %eax
13// CHECK-NEXT: 11017: a1 08 20 01 00 movl 73736, %eax
14// CHECK-NEXT: 1101c: e8 0f 00 00 00 calll 15 <.plt+0x20>
15// CHECK-NEXT: 11021: f3 90 pause
16// CHECK-NEXT: 11023: 0f ae e8 lfence
17// CHECK-NEXT: 11026: eb f9 jmp -7 <.plt+0x11>
18// CHECK-NEXT: 11028: cc int3
19// CHECK-NEXT: 11029: cc int3
20// CHECK-NEXT: 1102a: cc int3
21// CHECK-NEXT: 1102b: cc int3
22// CHECK-NEXT: 1102c: cc int3
23// CHECK-NEXT: 1102d: cc int3
24// CHECK-NEXT: 1102e: cc int3
25// CHECK-NEXT: 1102f: cc int3
26// CHECK-NEXT: 11030: 89 0c 24 movl %ecx, (%esp)
27// CHECK-NEXT: 11033: 8b 4c 24 04 movl 4(%esp), %ecx
28// CHECK-NEXT: 11037: 89 44 24 04 movl %eax, 4(%esp)
29// CHECK-NEXT: 1103b: 89 c8 movl %ecx, %eax
30// CHECK-NEXT: 1103d: 59 popl %ecx
31// CHECK-NEXT: 1103e: c3 retl
32// CHECK-NEXT: 1103f: cc int3
33// CHECK-NEXT: 11040: 50 pushl %eax
34// CHECK-NEXT: 11041: a1 0c 20 01 00 movl 73740, %eax
35// CHECK-NEXT: 11046: e8 e5 ff ff ff calll -27 <.plt+0x20>
36// CHECK-NEXT: 1104b: e9 d1 ff ff ff jmp -47 <.plt+0x11>
37// CHECK-NEXT: 11050: 68 00 00 00 00 pushl $0
38// CHECK-NEXT: 11055: e9 b6 ff ff ff jmp -74 <.plt>
39// CHECK-NEXT: 1105a: cc int3
40// CHECK-NEXT: 1105b: cc int3
41// CHECK-NEXT: 1105c: cc int3
42// CHECK-NEXT: 1105d: cc int3
43// CHECK-NEXT: 1105e: cc int3
44// CHECK-NEXT: 1105f: cc int3
45// CHECK-NEXT: 11060: 50 pushl %eax
46// CHECK-NEXT: 11061: a1 10 20 01 00 movl 73744, %eax
47// CHECK-NEXT: 11066: e8 c5 ff ff ff calll -59 <.plt+0x20>
48// CHECK-NEXT: 1106b: e9 b1 ff ff ff jmp -79 <.plt+0x11>
49// CHECK-NEXT: 11070: 68 08 00 00 00 pushl $8
50// CHECK-NEXT: 11075: e9 96 ff ff ff jmp -106 <.plt>
51// CHECK-NEXT: 1107a: cc int3
52// CHECK-NEXT: 1107b: cc int3
53// CHECK-NEXT: 1107c: cc int3
54// CHECK-NEXT: 1107d: cc int3
55// CHECK-NEXT: 1107e: cc int3
56// CHECK-NEXT: 1107f: cc int3
11// CHECK-NEXT: 401010: ff 35 04 20 40 00 pushl 4202500
12// CHECK-NEXT: 401016: 50 pushl %eax
13// CHECK-NEXT: 401017: a1 08 20 40 00 movl 4202504, %eax
14// CHECK-NEXT: 40101c: e8 0f 00 00 00 calll 15 <.plt+0x20>
15// CHECK-NEXT: 401021: f3 90 pause
16// CHECK-NEXT: 401023: 0f ae e8 lfence
17// CHECK-NEXT: 401026: eb f9 jmp -7 <.plt+0x11>
18// CHECK-NEXT: 401028: cc int3
19// CHECK-NEXT: 401029: cc int3
20// CHECK-NEXT: 40102a: cc int3
21// CHECK-NEXT: 40102b: cc int3
22// CHECK-NEXT: 40102c: cc int3
23// CHECK-NEXT: 40102d: cc int3
24// CHECK-NEXT: 40102e: cc int3
25// CHECK-NEXT: 40102f: cc int3
26// CHECK-NEXT: 401030: 89 0c 24 movl %ecx, (%esp)
27// CHECK-NEXT: 401033: 8b 4c 24 04 movl 4(%esp), %ecx
28// CHECK-NEXT: 401037: 89 44 24 04 movl %eax, 4(%esp)
29// CHECK-NEXT: 40103b: 89 c8 movl %ecx, %eax
30// CHECK-NEXT: 40103d: 59 popl %ecx
31// CHECK-NEXT: 40103e: c3 retl
32// CHECK-NEXT: 40103f: cc int3
33// CHECK-NEXT: 401040: 50 pushl %eax
34// CHECK-NEXT: 401041: a1 0c 20 40 00 movl 4202508, %eax
35// CHECK-NEXT: 401046: e8 e5 ff ff ff calll -27 <.plt+0x20>
36// CHECK-NEXT: 40104b: e9 d1 ff ff ff jmp -47 <.plt+0x11>
37// CHECK-NEXT: 401050: 68 00 00 00 00 pushl $0
38// CHECK-NEXT: 401055: e9 b6 ff ff ff jmp -74 <.plt>
39// CHECK-NEXT: 40105a: cc int3
40// CHECK-NEXT: 40105b: cc int3
41// CHECK-NEXT: 40105c: cc int3
42// CHECK-NEXT: 40105d: cc int3
43// CHECK-NEXT: 40105e: cc int3
44// CHECK-NEXT: 40105f: cc int3
45// CHECK-NEXT: 401060: 50 pushl %eax
46// CHECK-NEXT: 401061: a1 10 20 40 00 movl 4202512, %eax
47// CHECK-NEXT: 401066: e8 c5 ff ff ff calll -59 <.plt+0x20>
48// CHECK-NEXT: 40106b: e9 b1 ff ff ff jmp -79 <.plt+0x11>
49// CHECK-NEXT: 401070: 68 08 00 00 00 pushl $8
50// CHECK-NEXT: 401075: e9 96 ff ff ff jmp -106 <.plt>
51// CHECK-NEXT: 40107a: cc int3
52// CHECK-NEXT: 40107b: cc int3
53// CHECK-NEXT: 40107c: cc int3
54// CHECK-NEXT: 40107d: cc int3
55// CHECK-NEXT: 40107e: cc int3
56// CHECK-NEXT: 40107f: cc int3
5757
5858// CHECK: Contents of section .got.plt:
59// CHECK-NEXT: 00300100 00000000 00000000 50100100
60// CHECK-NEXT: 70100100
59// CHECK-NEXT: 00304000 00000000 00000000 50104000
60// CHECK-NEXT: 70104000
6161
6262.global _start
6363_start:
deps/lld/test/ELF/image-base.s+3
......@@ -3,6 +3,9 @@
33# RUN: ld.lld -image-base=0x1000000 %t -o %t1
44# 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
69# RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s
710# 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 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o
3// RUN: rm -f %t.a
34// RUN: llvm-ar rc %t.a %ta.o
45// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
56// 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 @@
4848// We used to fail to identify this incompatibility and crash trying to
4949// read a 64 bit file as a 32 bit one.
5050// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o
51// RUN: rm -f %t.a
5152// RUN: llvm-ar rc %t.a %ta.o
5253// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
5354// 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 @@
5050
5151# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
5252# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
53# ERR8: , expected, but got y
53# 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
5455# 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 @@
33// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
44// 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
96.section .foo,"aM",@progbits,4
107.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 @@
44
55# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o
66# RUN: ld.lld -r -o %t2.o --script %s %t1.o
7# RUN: llvm-readelf -s %t2.o | FileCheck %s
7# RUN: llvm-readelf -S %t2.o | FileCheck %s
88
99# CHECK: Section Headers:
1010# CHECK-NEXT: Name Type Address Off Size ES Flg Lk Inf Al
deps/lld/test/ELF/linkerscript/align4.test-1
......@@ -4,7 +4,6 @@
44# RUN: llvm-objdump -t %t | FileCheck %s
55
66# CHECK-LABEL: SYMBOL TABLE:
7# CHECK-NEXT: 0000000000000000 *UND* 00000000
87# CHECK-NEXT: 0000000000014008 .text 00000000 _start
98# CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
109# CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR
deps/lld/test/ELF/linkerscript/discard-section-err.s+6-14
......@@ -7,25 +7,17 @@
77# RUN: FileCheck -check-prefix=SHSTRTAB %s
88# SHSTRTAB: discarding .shstrtab section is not allowed
99
10## We allow discarding .dynamic, check we don't crash.
1011# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script
11# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
12# RUN: FileCheck -check-prefix=DYNAMIC %s
13# DYNAMIC: discarding .dynamic section is not allowed
12# RUN: ld.lld -pie -o %t --script %t.script %t.o
1413
14## We allow discarding .dynsym, check we don't crash.
1515# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script
16# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
17# RUN: FileCheck -check-prefix=DYNSYM %s
18# DYNSYM: discarding .dynsym section is not allowed
16# RUN: ld.lld -pie -o %t --script %t.script %t.o
1917
18## We allow discarding .dynstr, check we don't crash.
2019# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script
21# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
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
20# RUN: ld.lld -pie -o %t --script %t.script %t.o
2921
3022# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.dyn) } }" > %t.script
3123# 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 @@
4343# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o
4444# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4545# RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o
46# RUN: rm -f %t.testdir1/lib1.a %t.testdir2/lib2.a
4647# RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o
4748# 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 @@
2929# RUN: ld.lld -o %t --script %t.script %t.o
3030# 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
3241.section .foo,"a",@progbits
3342.zero 1
deps/lld/test/ELF/linkerscript/lazy-symbols.test+1
......@@ -1,5 +1,6 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
3# RUN: rm -f %tar
34# RUN: llvm-ar rcs %tar %t1
45# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t2
56# RUN: ld.lld %t2 %tar --script %s -o %tout
deps/lld/test/ELF/linkerscript/map-file.test+4-4
......@@ -44,10 +44,10 @@ SECTIONS {
4444# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 )
4545# CHECK-NEXT: 225d 225d 0 1 foo = .
4646# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26
47# CHECK-NEXT: 225d 0 0 1 sym1 = .
48# CHECK-NEXT: 225d 0 500 1 . += 0x500
49# CHECK-NEXT: 275d 0 0 1 sym2 = .
50# CHECK-NEXT: 275d 0 0 1 PROVIDE ( sym3 = 42 )
47# CHECK-NEXT: 225d 225d 0 1 sym1 = .
48# CHECK-NEXT: 225d 225d 500 1 . += 0x500
49# CHECK-NEXT: 275d 275d 0 1 sym2 = .
50# CHECK-NEXT: 275d 275d 0 1 PROVIDE ( sym3 = 42 )
5151# CHECK-NEXT: 2760 2760 10 4 .text
5252# CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
5353# CHECK-NEXT: 0 0 8 1 .comment
deps/lld/test/ELF/linkerscript/map-file2.test+12-10
......@@ -8,6 +8,7 @@ SECTIONS {
88 .aaa : { *(.aaa.*) }
99 .bbb : AT(0x2000) { *(.bbb.*) }
1010 .ccc : AT(0x3000) { *(.ccc.*) }
11 . += 0x100;
1112 .ddd : {
1213 BYTE(0x11)
1314 . += 0x100;
......@@ -24,16 +25,17 @@ SECTIONS {
2425# CHECK-NEXT: 1008 2000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb)
2526# CHECK-NEXT: 1010 3000 8 1 .ccc
2627# CHECK-NEXT: 1010 3000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc)
27# CHECK-NEXT: 1018 3008 109 1 .ddd
28# CHECK-NEXT: 1018 3008 1 1 BYTE ( 0x11 )
29# CHECK-NEXT: 1019 3009 100 1 . += 0x100
30# CHECK-NEXT: 1119 3109 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd)
31# CHECK-NEXT: 1128 3118 34 8 .eh_frame
32# CHECK-NEXT: 1128 3118 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0)
33# CHECK-NEXT: 115c 314c 1 4 .text
34# CHECK-NEXT: 115c 314c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text)
35# CHECK-NEXT: 115c 314c 0 1 f(int)
36# CHECK-NEXT: 115c 314c 0 1 _start
28# CHECK-NEXT: 1018 3008 100 1 . += 0x100
29# CHECK-NEXT: 1118 3108 109 1 .ddd
30# CHECK-NEXT: 1118 3108 1 1 BYTE ( 0x11 )
31# CHECK-NEXT: 1119 3109 100 1 . += 0x100
32# CHECK-NEXT: 1219 3209 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd)
33# CHECK-NEXT: 1228 3218 34 8 .eh_frame
34# CHECK-NEXT: 1228 3218 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0)
35# CHECK-NEXT: 125c 324c 1 4 .text
36# CHECK-NEXT: 125c 324c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text)
37# CHECK-NEXT: 125c 324c 0 1 f(int)
38# CHECK-NEXT: 125c 324c 0 1 _start
3739# CHECK-NEXT: 0 0 8 1 .comment
3840# CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
3941# 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 @@
1616# RUN: .foo : {*(.foo)} :foo \
1717# RUN: }" > %t.script
1818# RUN: ld.lld -o %t --script %t.script %t.o
19# RUN: llvm-readelf -s -l %t | FileCheck %s
19# RUN: llvm-readelf -S -l %t | FileCheck %s
2020# RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s
2121
2222# CHECK: Program Headers:
deps/lld/test/ELF/linkerscript/non-alloc.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script
55# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
6# RUN: llvm-readelf -s -l %t | FileCheck %s
6# RUN: llvm-readelf -S -l %t | FileCheck %s
77
88# Test that we create all necessary PT_LOAD. We use to stop at the first
99# 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 @@
1010# RUN: /DISCARD/ : { *(.comment) } \
1111# RUN: }" > %t.script
1212# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -s -symbols %t | FileCheck %s
13# RUN: llvm-readelf -S -symbols %t | FileCheck %s
1414
1515# CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 4096
1616# CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end
deps/lld/test/ELF/linkerscript/orphan-phdrs.s+1-1
......@@ -10,7 +10,7 @@
1010# RUN: .rw : { *(.rw) } \
1111# RUN: }" > %t.script
1212# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -s -l %t | FileCheck %s
13# RUN: llvm-readelf -S -l %t | FileCheck %s
1414
1515## Check that the orphan section is placed correctly and belongs to
1616## 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 @@
11# REQUIRES: x86
2
23# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
34# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
45# 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
511# CHECK: error: output file too large
612
713.global _start
deps/lld/test/ELF/linkerscript/phdrs.s+8
......@@ -130,6 +130,14 @@
130130
131131# 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
133141.global _start
134142_start:
135143 nop
deps/lld/test/ELF/linkerscript/provide-shared2.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: ld.lld -o %t --script %t.script %t.o %t2.so
77# 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
1111.global _start
1212_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 {
77 ph_text PT_LOAD FILEHDR PHDRS FLAGS (0x1 | 0x4);
88}
99
10SECTIONS {
10SECTIONS {
1111 . = 0xffffffff20000000;
1212 .text : { *(.text*) } : ph_text
1313 .test 0x1000 : { BYTE(0) }
......@@ -18,5 +18,5 @@ SECTIONS {
1818## with VA 0xffffffff20000000. That might be technically correct, but most probably
1919## is a result of a broken script file and causes file offset calculation overflow.
2020## 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 overflows
21# ERR: error: unable to place section .text at file offset [0xFFFFFFFF20000000, 0xFFFFFFFF20000000]; check your linker script for overflows
2222# ERR-NOT: unable to place section .bss
deps/lld/test/ELF/linkerscript/segment-none.s+2-2
......@@ -9,7 +9,7 @@
99# RUN: .foo : {*(.foo)} :NONE \
1010# RUN: }" > %t.script
1111# RUN: ld.lld -o %t --script %t.script %t.o
12# RUN: llvm-readelf -s -l %t | FileCheck %s
12# RUN: llvm-readelf -S -l %t | FileCheck %s
1313
1414## Test that section .foo is placed in segment NONE when assigned to segment
1515## NONE in the linker script and segment NONE is defined.
......@@ -19,7 +19,7 @@
1919# RUN: .foo : {*(.foo)} :NONE \
2020# RUN: }" > %t.script
2121# RUN: ld.lld -o %t --script %t.script %t.o
22# RUN: llvm-readelf -s -l %t | FileCheck --check-prefix=DEFINED %s
22# RUN: llvm-readelf -S -l %t | FileCheck --check-prefix=DEFINED %s
2323
2424# CHECK: Section to Segment mapping:
2525# CHECK-NEXT: Segment Sections...
deps/lld/test/ELF/linkerscript/sizeof.s-1
......@@ -18,7 +18,6 @@
1818# CHECK-NEXT: 2 .bbb 00000010
1919# CHECK-NEXT: 3 .ccc 00000018
2020# CHECK: SYMBOL TABLE:
21# CHECK-NEXT: 0000000000000000 *UND* 00000000
2221# CHECK-NEXT: .text 00000000 _start
2322# CHECK-NEXT: 0000000000000008 *ABS* 00000000 _aaa
2423# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
deps/lld/test/ELF/linkerscript/sizeofheaders.s-1
......@@ -9,7 +9,6 @@
99# RUN: llvm-objdump -t %t1 | FileCheck %s
1010
1111#CHECK: SYMBOL TABLE:
12#CHECK-NEXT: 0000000000000000 *UND* 00000000
1312#CHECK-NEXT: 00000000000000e8 .text 00000000 _start
1413#CHECK-NEXT: 00000000000000e8 *ABS* 00000000 _size
1514
deps/lld/test/ELF/linkerscript/sort-init.s+4-2
......@@ -1,16 +1,18 @@
11# REQUIRES: x86
22# 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.script
3# RUN: echo "SECTIONS { .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array.* foo*)) } }" > %t1.script
44# RUN: ld.lld --script %t1.script %t1.o -o %t2
55# RUN: llvm-objdump -s %t2 | FileCheck %s
66
77# CHECK: Contents of section .init_array:
8# CHECK-NEXT: 03020000 00000000 010405
8# CHECK-NEXT: 03020000 00060000 010405
99
1010.globl _start
1111_start:
1212 nop
1313
14.section foo, "aw", @init_array
15 .byte 6
1416.section .init_array, "aw", @init_array
1517 .align 8
1618 .byte 1
deps/lld/test/ELF/linkerscript/sort-non-script.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script
55# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
6# RUN: llvm-readelf -s %t | FileCheck %s
6# RUN: llvm-readelf -S %t | FileCheck %s
77
88# CHECK: .dynsym {{.*}} A
99# CHECK-NEXT: .hash {{.*}} A
deps/lld/test/ELF/linkerscript/symbol-assignexpr.s-1
......@@ -25,7 +25,6 @@
2525# RUN: llvm-objdump -t %t1 | FileCheck %s
2626
2727# CHECK: SYMBOL TABLE:
28# CHECK-NEXT: 0000000000000000 *UND* 00000000
2928# CHECK-NEXT: 0000000000000000 .text 00000000 _start
3029# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
3130# 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 @@
1313# RUN: llvm-objdump -t %t1 | FileCheck %s
1414
1515# CHECK: SYMBOL TABLE:
16# CHECK-NEXT: 0000000000000000 *UND* 00000000
1716# CHECK-NEXT: 0000000000008000 .text 00000000 _start
1817# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
1918# 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 @@
77# RUN: }" > %t.script
88# RUN: ld.lld -shared -o %t.so --script %t.script %t.o
99
10# RUN: llvm-readelf -s %t.so | FileCheck %s
10# RUN: llvm-readelf -S %t.so | FileCheck %s
1111# CHECK-NOT: .got
1212# CHECK-NOT: .plt
1313# CHECK: .dynsym
deps/lld/test/ELF/linkerscript/version-script.s+3-3
......@@ -14,11 +14,11 @@
1414# CHECK: Symbols [
1515# CHECK-NEXT: Symbol {
1616# CHECK-NEXT: Version: 0
17# CHECK-NEXT: Name: @
17# CHECK-NEXT: Name:
1818# CHECK-NEXT: }
1919# CHECK-NEXT: Symbol {
2020# CHECK-NEXT: Version: 0
21# CHECK-NEXT: Name: und@
21# CHECK-NEXT: Name: und
2222# CHECK-NEXT: }
2323# CHECK-NEXT: Symbol {
2424# CHECK-NEXT: Version: 2
......@@ -41,7 +41,7 @@
4141# UNDEF: Symbols [
4242# UNDEF-NEXT: Symbol {
4343# UNDEF-NEXT: Version: 0
44# UNDEF-NEXT: Name: @
44# UNDEF-NEXT: Name:
4545# UNDEF-NEXT: }
4646# UNDEF-NEXT: Symbol {
4747# UNDEF-NEXT: Version: 2
deps/lld/test/ELF/local-dynamic.s+2-2
......@@ -65,7 +65,7 @@
6565
6666// CHECK: DynamicSymbols [
6767// CHECK-NEXT: Symbol {
68// CHECK-NEXT: Name: @
68// CHECK-NEXT: Name:
6969// CHECK-NEXT: Value: 0x0
7070// CHECK-NEXT: Size: 0
7171// CHECK-NEXT: Binding: Local
......@@ -74,7 +74,7 @@
7474// CHECK-NEXT: Section: Undefined
7575// CHECK-NEXT: }
7676// CHECK-NEXT: Symbol {
77// CHECK-NEXT: Name: _start@
77// CHECK-NEXT: Name: _start
7878// CHECK-NEXT: Value:
7979// CHECK-NEXT: Size: 0
8080// 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 @@
66# RUN: -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null
77
88# 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'
10# CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'
9# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'
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 @@
11; REQUIRES: x86
2; NetBSD: noatime mounts currently inhibit 'touch' from updating atime
3; UNSUPPORTED: system-netbsd
24
35; RUN: opt -module-hash -module-summary %s -o %t.o
46; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o
......@@ -19,6 +21,10 @@
1921; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o
2022; 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
2228; This should remove it.
2329; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t3 %t2.o %t.o
2430; RUN: ls %t.cache | count 4
......@@ -31,6 +37,20 @@
3137; 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
3238; 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
3454target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3555target triple = "x86_64-unknown-linux-gnu"
3656
deps/lld/test/ELF/lto/data-ordering-lto.s+1-1
......@@ -8,7 +8,7 @@
88# RUN: echo "pat " >> %t_order_lto.txt
99
1010# 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 %s
11# RUN: llvm-readelf --symbols %t2.out| FileCheck %s
1212
1313# Check that the order is tin -> dipsy -> pat.
1414
deps/lld/test/ELF/lto/defsym.ll+2-2
......@@ -3,14 +3,14 @@
33; RUN: llvm-as %s -o %t.o
44; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o
55; 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 %s
6; RUN: llvm-readelf --symbols %t.so.lto.o | FileCheck --check-prefix=OBJ %s
77; RUN: llvm-objdump -d %t.so | FileCheck %s
88
99; ThinLTO
1010; RUN: opt -module-summary %s -o %t.o
1111; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o
1212; 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 %s
13; RUN: llvm-readelf --symbols %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s
1414; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN
1515
1616; OBJ: UND bar2
deps/lld/test/ELF/lto/dynamic-list.ll+1-1
......@@ -4,7 +4,7 @@
44; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
55; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
66
7; CHECK: Name: foo@
7; CHECK: Name: foo
88; CHECK-NEXT: Value: 0x1010
99; CHECK-NEXT: Size: 1
1010; 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 @@
22; RUN: rm -f %t.a
33; RUN: llvm-as -o %t.o %s
44; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll
5; RUN: llvm-ar rcs %t.a %t2.o
5; 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
67; RUN: ld.lld -o %t %t.o %t.a
78; 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
913; CHECK: T _start
1014; CHECK: T memcpy
1115
deps/lld/test/ELF/lto/ltopasses-custom.ll+2-2
......@@ -27,11 +27,11 @@ define void @barrier() {
2727; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
2828; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \
2929; RUN: FileCheck %s --check-prefix=INVALID
30; INVALID: unable to parse pass pipeline description: iamnotapass
30; INVALID: unable to parse pass pipeline description 'iamnotapass': unknown pass name 'iamnotapass'
3131
3232; Check that invalid AA pipelines are rejected gracefully.
3333; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
3434; RUN: --lto-newpm-passes=globaldce --lto-aa-pipeline=patatino \
3535; RUN: -shared 2>&1 | \
3636; RUN: FileCheck %s --check-prefix=INVALIDAA
37; INVALIDAA: unable to parse AA pipeline description: patatino
37; INVALIDAA: unknown alias analysis name 'patatino'
deps/lld/test/ELF/lto/opt-remarks.ll+6-4
......@@ -23,9 +23,10 @@
2323; YAML-NEXT: - Callee: tinkywinky
2424; YAML-NEXT: - String: ' inlined into '
2525; YAML-NEXT: - Caller: main
26; YAML-NEXT: - String: ' with cost='
26; YAML-NEXT: - String: ' with '
27; YAML-NEXT: - String: '(cost='
2728; YAML-NEXT: - Cost: '0'
28; YAML-NEXT: - String: ' (threshold='
29; YAML-NEXT: - String: ', threshold='
2930; YAML-NEXT: - Threshold: '337'
3031; YAML-NEXT: - String: ')'
3132; YAML-NEXT: ...
......@@ -39,9 +40,10 @@
3940; YAML-HOT-NEXT: - Callee: tinkywinky
4041; YAML-HOT-NEXT: - String: ' inlined into '
4142; YAML-HOT-NEXT: - Caller: main
42; YAML-HOT-NEXT: - String: ' with cost='
43; YAML-HOT-NEXT: - String: ' with '
44; YAML-HOT-NEXT: - String: '(cost='
4345; YAML-HOT-NEXT: - Cost: '0'
44; YAML-HOT-NEXT: - String: ' (threshold='
46; YAML-HOT-NEXT: - String: ', threshold='
4547; YAML-HOT-NEXT: - Threshold: '337'
4648; YAML-HOT-NEXT: - String: ')'
4749; 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 @@
4141; CHECK-NEXT: Section: .text.foo
4242; CHECK-NEXT: }
4343; 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 {
4453; CHECK-NEXT: Name: foo
4554; CHECK-NEXT: Value: 0x0
4655; CHECK-NEXT: Size: 1
deps/lld/test/ELF/lto/section-name.ll+2-2
......@@ -1,9 +1,9 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o -o %t.so -shared
4; RUN: llvm-readelf -s %t.so | FileCheck %s
4; RUN: llvm-readelf -S %t.so | FileCheck %s
55; RUN: ld.lld %t.o -o %t.so -shared --gc-sections
6; RUN: llvm-readelf -s %t.so | FileCheck --check-prefix=GC %s
6; RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=GC %s
77
88target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
99target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/shlib-undefined.ll+1-1
......@@ -6,7 +6,7 @@
66; RUN: ld.lld -o %t %t.o %t2.so
77; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
88
9; CHECK: Name: __progname@
9; CHECK: Name: __progname
1010; CHECK-NEXT: Value: 0x201010
1111; CHECK-NEXT: Size: 1
1212; CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/lto/symbol-ordering-lto.s+1-1
......@@ -8,7 +8,7 @@
88# RUN: echo "pat " >> %t_order_lto.txt
99
1010# 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 %s
11# RUN: llvm-readelf --symbols %t2.out| FileCheck %s
1212
1313# Check that the order is tin -> _start -> pat.
1414
deps/lld/test/ELF/lto/thinlto-obj-path.ll+2-1
......@@ -7,7 +7,8 @@
77; RUN: rm -f %t4.o
88; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3
99; RUN: llvm-readobj -h %t4.o | FileCheck %s
10; RUN: llvm-nm %t4.o | count 0
10; RUN: llvm-nm %t4.o 2>&1 | FileCheck %s -check-prefix=NO-SYMBOLS
11; NO-SYMBOLS: no symbols
1112
1213; CHECK: Format: ELF64-x86-64
1314
deps/lld/test/ELF/lto/thinlto-object-suffix-replace.ll+6-6
......@@ -29,12 +29,12 @@
2929; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR1
3030; 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 name
33; RUN: rm -f %t1.o
34; RUN: not ld.lld --plugin-opt=thinlto-index-only \
35; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \
36; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR2
37; ERR2: error: -thinlto-object-suffix-replace=.abc;.o was given, but {{.*}} does not end with the suffix
32; If filename does not end with old suffix, no suffix change should occur,
33; so ".thinlto.bc" will simply be appended to the input file name.
34; RUN: rm -f %t1.thinlink.bc.thinlto.bc
35; RUN: ld.lld --plugin-opt=thinlto-index-only \
36; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc -o /dev/null
37; RUN: ls %t1.thinlink.bc.thinlto.bc
3838
3939target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4040target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/undefined-puts.ll+1-1
......@@ -25,4 +25,4 @@ declare i32 @printf(i8*, ...)
2525
2626; CHECK: DynamicSymbols [
2727; 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() {
2121
2222; DSO: DynamicSymbols [
2323; DSO: Symbol {
24; DSO: Name: @ (0)
24; DSO: Name:
2525; DSO: Value: 0x0
2626; DSO: Size: 0
2727; DSO: Binding: Local
deps/lld/test/ELF/lto/wrap-2.ll+6-2
......@@ -28,11 +28,15 @@
2828; THIN-NEXT: jmp{{.*}}<bar>
2929
3030; Check that bar and __wrap_bar retain their original binding.
31; BIND: Name: __wrap_bar
31; BIND: Name: bar
3232; BIND-NEXT: Value:
3333; BIND-NEXT: Size:
3434; BIND-NEXT: Binding: Local
35; BIND: Name: bar
35; BIND: Name: __real_bar
36; BIND-NEXT: Value:
37; BIND-NEXT: Size:
38; BIND-NEXT: Binding: Local
39; BIND: Name: __wrap_bar
3640; BIND-NEXT: Value:
3741; BIND-NEXT: Size:
3842; BIND-NEXT: Binding: Local
deps/lld/test/ELF/map-file-i686.s+12-12
......@@ -7,15 +7,15 @@
77_start:
88 nop
99
10// CHECK: VMA LMA Size Align Out In Symbol
11// CHECK-NEXT: 11000 11000 1 4 .text
12// CHECK-NEXT: 11000 11000 1 4 {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)
13// CHECK-NEXT: 11000 11000 0 1 _start
14// CHECK-NEXT: 0 0 8 1 .comment
15// CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
16// CHECK-NEXT: 0 0 20 4 .symtab
17// CHECK-NEXT: 0 0 20 4 <internal>:(.symtab)
18// CHECK-NEXT: 0 0 2a 1 .shstrtab
19// CHECK-NEXT: 0 0 2a 1 <internal>:(.shstrtab)
20// CHECK-NEXT: 0 0 8 1 .strtab
21// CHECK-NEXT: 0 0 8 1 <internal>:(.strtab)
10// CHECK: VMA LMA Size Align Out In Symbol
11// CHECK-NEXT: 401000 401000 1 4 .text
12// CHECK-NEXT: 401000 401000 1 4 {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)
13// CHECK-NEXT: 401000 401000 0 1 _start
14// CHECK-NEXT: 0 0 8 1 .comment
15// CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
16// CHECK-NEXT: 0 0 20 4 .symtab
17// CHECK-NEXT: 0 0 20 4 <internal>:(.symtab)
18// CHECK-NEXT: 0 0 2a 1 .shstrtab
19// CHECK-NEXT: 0 0 2a 1 <internal>:(.shstrtab)
20// CHECK-NEXT: 0 0 8 1 .strtab
21// CHECK-NEXT: 0 0 8 1 <internal>:(.strtab)
deps/lld/test/ELF/merge-string-error.s+1-1
......@@ -8,4 +8,4 @@
88 .data
99 .long .rodata.str1.1 + 4
1010
11// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): entry is past the end of the section
11// 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:
4141# ^-- v2+4 ^-- v1
4242
4343# SYM: SYMBOL TABLE:
44# SYM: 00020000 l .data 00000004 v1
45# SYM: 00020004 g .data 00000008 v2
44# SYM: 00020000 l O .data 00000004 v1
45# SYM: 00020004 g O .data 00000008 v2
4646
4747# REL: Relocations [
4848# REL-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-64.s+2-2
......@@ -25,8 +25,8 @@ v2:
2525
2626
2727# SYM: SYMBOL TABLE:
28# SYM: 00020000 l .data 00000004 v1
29# SYM: 00020008 g .data 00000008 v2
28# SYM: 00020000 l O .data 00000004 v1
29# SYM: 00020008 g O .data 00000008 v2
3030
3131# CHECK: Relocations [
3232# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-dynamic.s+3-3
......@@ -97,9 +97,9 @@
9797# DSO-NEXT: Size: 8
9898# DSO: ]
9999# DSO: DynamicSymbols [
100# DSO: Name: @
101# DSO: Name: __start@
102# DSO: Name: _foo@
100# DSO: Name:
101# DSO: Name: __start
102# DSO: Name: _foo
103103# DSO: ]
104104# DSO: DynamicSection [
105105# DSO-NEXT: Tag Type Name/Value
deps/lld/test/ELF/mips-dynsym-sort.s+3-3
......@@ -36,7 +36,7 @@ __start:
3636# the MIPS rules. v2 comes first as it is not in the GOT.
3737# v1 and v3 are sorted according to their order in the GOT.
3838# CHECK: DynamicSymbols [
39# CHECK: Name: v2@
40# CHECK: Name: v3@
41# CHECK: Name: v1@
39# CHECK: Name: v2
40# CHECK: Name: v3
41# CHECK: Name: v1
4242# CHECK: ]
deps/lld/test/ELF/mips-gnu-hash.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
88# 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
1212 .globl __start
1313__start:
deps/lld/test/ELF/mips-got-and-copy.s+2-2
......@@ -32,7 +32,7 @@
3232# CHECK-NEXT: Value: 0x[[DATA0]]
3333# CHECK-NEXT: Type: Object
3434# CHECK-NEXT: Section: .bss
35# CHECK-NEXT: Name: data0@
35# CHECK-NEXT: Name: data0
3636# CHECK-NEXT: }
3737# CHECK-NEXT: Entry {
3838# CHECK-NEXT: Address:
......@@ -41,7 +41,7 @@
4141# CHECK-NEXT: Value: 0x[[DATA1]]
4242# CHECK-NEXT: Type: Object
4343# CHECK-NEXT: Section: .bss
44# CHECK-NEXT: Name: data1@
44# CHECK-NEXT: Name: data1
4545# CHECK-NEXT: }
4646# CHECK-NEXT: ]
4747# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
deps/lld/test/ELF/mips-got-extsym.s+1-1
......@@ -43,7 +43,7 @@
4343# CHECK-NEXT: Value: 0x0
4444# CHECK-NEXT: Type: None
4545# CHECK-NEXT: Section: Undefined
46# CHECK-NEXT: Name: _foo@
46# CHECK-NEXT: Name: _foo
4747# CHECK-NEXT: }
4848# CHECK-NEXT: ]
4949
deps/lld/test/ELF/mips-got-relocs.s+2-2
......@@ -48,7 +48,7 @@ v1:
4848# EXE_SYM: SYMBOL TABLE:
4949# EXE_SYM: 00038000 .got 00000000 .hidden _gp
5050# ^-- .got + GP offset (0x7ff0)
51# EXE_SYM: 00030000 g .data 00000004 v1
51# EXE_SYM: 00030000 g O .data 00000004 v1
5252
5353
5454# EXE_GOT_BE: Contents of section .got:
......@@ -72,7 +72,7 @@ v1:
7272# DSO_SYM: SYMBOL TABLE:
7373# DSO_SYM: 00028000 .got 00000000 .hidden _gp
7474# ^-- .got + GP offset (0x7ff0)
75# DSO_SYM: 00020000 g .data 00000004 v1
75# DSO_SYM: 00020000 g O .data 00000004 v1
7676
7777# DSO_GOT_BE: Contents of section .got:
7878# DSO_GOT_BE: 20010 00000000 80000000 00020000
deps/lld/test/ELF/mips-got16-relocatable.s+2-6
......@@ -14,9 +14,7 @@
1414# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
1515# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 0
1616# OBJ-NEXT: 00000004: R_MIPS_LO16 .data
17# OBJ-NEXT: 8: ef ef ef ef <unknown>
18# OBJ-NEXT: c: ef ef ef ef <unknown>
19# OBJ-NEXT: 10: 8f 99 00 00 lw $25, 0($gp)
17# OBJ: 10: 8f 99 00 00 lw $25, 0($gp)
2018# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data
2119# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 16
2220# OBJ-NEXT: 00000014: R_MIPS_LO16 .data
......@@ -25,9 +23,7 @@
2523# SO-NEXT: .text:
2624# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
2725# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
28# SO-NEXT: 10008: ef ef ef ef <unknown>
29# SO-NEXT: 1000c: ef ef ef ef <unknown>
30# SO-NEXT: 10010: 8f 99 80 18 lw $25, -32744($gp)
26# SO: 10010: 8f 99 80 18 lw $25, -32744($gp)
3127# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 16
3228
3329 .text
deps/lld/test/ELF/mips-got16.s+1-1
......@@ -96,7 +96,7 @@
9696# GOT-NEXT: Value: 0x0
9797# GOT-NEXT: Type: None
9898# GOT-NEXT: Section: Undefined
99# GOT-NEXT: Name: foo@
99# GOT-NEXT: Name: foo
100100# GOT-NEXT: }
101101# GOT-NEXT: ]
102102# GOT-NEXT: Number of TLS and multi-GOT entries: 0
deps/lld/test/ELF/mips-hilo.s+3-3
......@@ -47,6 +47,6 @@ g1:
4747# ^-- %lo(l1-4)
4848
4949# CHECK: SYMBOL TABLE:
50# CHECK: 0030000 l .data 00000004 l1
51# CHECK: 0020000 .text 00000000 __start
52# CHECK: 0030004 g .data 00000004 g1
50# CHECK: 0030000 l O .data 00000004 l1
51# CHECK: 0020000 .text 00000000 __start
52# CHECK: 0030004 g O .data 00000004 g1
deps/lld/test/ELF/mips-mgot.s+7-7
......@@ -18,13 +18,13 @@
1818# CHECK-NEXT: 60040 00000000 00000000 00000000
1919
2020# CHECK: SYMBOL TABLE:
21# CHECK: 00000000 l .tdata 00000000 loc0
22# CHECK: 00010000 .text 00000000 foo0
23# CHECK: 00000000 g .tdata 00000000 tls0
24# CHECK: 00010020 .text 00000000 foo1
25# CHECK: 00000004 g .tdata 00000000 tls1
26# CHECK: 00010030 .text 00000000 foo2
27# CHECK: 00000008 g .tdata 00000000 tls2
21# CHECK: 00000000 l O .tdata 00000000 loc0
22# CHECK: 00010000 .text 00000000 foo0
23# CHECK: 00000000 g O .tdata 00000000 tls0
24# CHECK: 00010020 .text 00000000 foo1
25# CHECK: 00000004 g O .tdata 00000000 tls1
26# CHECK: 00010030 .text 00000000 foo2
27# CHECK: 00000008 g O .tdata 00000000 tls2
2828
2929# GOT: Relocations [
3030# GOT-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-micro-jal.s+3-9
......@@ -57,9 +57,7 @@
5757# EB-NEXT: 20022: 45 f9 jalrs16 $25
5858# EB-NEXT: 20024: 0f 83 move $gp, $3
5959# EB-NEXT: 20026: 0c 00 nop
60# EB-NEXT: 20028: 00 00 00 00 nop
61# EB-NEXT: 2002c: 00 00 00 00 nop
62
60# EB-NEXT: ...
6361# EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 65500
6462# EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2)
6563# EB-NEXT: 20038: 45 99 jr16 $25
......@@ -76,9 +74,7 @@
7674# EL-NEXT: 20022: f9 45 jalrs16 $25
7775# EL-NEXT: 20024: 83 0f move $gp, $3
7876# EL-NEXT: 20026: 00 0c nop
79# EL-NEXT: 20028: 00 00 00 00 nop
80# EL-NEXT: 2002c: 00 00 00 00 nop
81
77# EL-NEXT: ...
8278# EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 65500
8379# EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2)
8480# EL-NEXT: 20038: 99 45 jr16 $25
......@@ -127,9 +123,7 @@
127123# MIXED-NEXT: 20032: 45 f9 jalrs16 $25
128124# MIXED-NEXT: 20034: 0f 83 move $gp, $3
129125# MIXED-NEXT: 20036: 0c 00 nop
130# MIXED-NEXT: 20038: 00 00 00 00 nop
131# MIXED-NEXT: 2003c: 00 00 00 00 nop
132
126# MIXED-NEXT: ...
133127# MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484
134128# MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2)
135129# MIXED-NEXT: 20048: 45 99 jr16 $25
deps/lld/test/ELF/mips-micro-plt.s+1-1
......@@ -80,7 +80,7 @@
8080# CHECK-NEXT: Value: 0x20041
8181# CHECK-NEXT: Type: Function
8282# CHECK-NEXT: Section: Undefined
83# CHECK-NEXT: Name: foo0@
83# CHECK-NEXT: Name: foo0
8484# CHECK-NEXT: }
8585# CHECK-NEXT: ]
8686# CHECK-NEXT: }
deps/lld/test/ELF/mips-npic-call-pic-os.s+18-17
......@@ -19,37 +19,37 @@
1919# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
2020# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
2121# CHECK-NEXT: 2000c: 00 00 00 00 nop
22
2223# CHECK: __LA25Thunk_foo1b:
2324# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
2425# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
2526# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
2627# CHECK-NEXT: 2001c: 00 00 00 00 nop
28
2729# CHECK: foo1a:
2830# CHECK-NEXT: 20020: 00 00 00 00 nop
31
2932# CHECK: foo1b:
3033# CHECK-NEXT: 20024: 00 00 00 00 nop
34
3135# CHECK: __LA25Thunk_foo2:
3236# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
3337# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
3438# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
3539# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
40
3841# CHECK: foo2:
3942# CHECK-NEXT: 20040: 00 00 00 00 nop
43
4044# CHECK: __LA25Thunk_fpic:
4145# CHECK-NEXT: 20044: 3c 19 00 02 lui $25, 2
4246# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>
4347# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 96
4448# CHECK-NEXT: 20050: 00 00 00 00 nop
45# CHECK-NEXT: 20054: ef ef ef ef <unknown>
46# CHECK-NEXT: 20058: ef ef ef ef <unknown>
47# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
49
4850# CHECK: fpic:
4951# CHECK-NEXT: 20060: 00 00 00 00 nop
50# CHECK-NEXT: 20064: ef ef ef ef <unknown>
51# CHECK-NEXT: 20068: ef ef ef ef <unknown>
52# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
52
5353# CHECK: fnpic:
5454# CHECK-NEXT: 20070: 00 00 00 00 nop
5555# CHECK-NEXT: Disassembly of section differentos:
......@@ -79,40 +79,41 @@
7979# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
8080# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
8181# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82
8283# REVERSE: __LA25Thunk_foo1b:
8384# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
8485# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
8586# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
8687# REVERSE-NEXT: 2001c: 00 00 00 00 nop
88
8789# REVERSE: foo1a:
8890# REVERSE-NEXT: 20020: 00 00 00 00 nop
91
8992# REVERSE: foo1b:
9093# REVERSE-NEXT: 20024: 00 00 00 00 nop
94
9195# REVERSE: __LA25Thunk_foo2:
9296# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
9397# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
9498# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
9599# REVERSE-NEXT: 20034: 00 00 00 00 nop
96# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
97# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
100
98101# REVERSE: foo2:
99102# REVERSE-NEXT: 20040: 00 00 00 00 nop
100# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
101# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
102# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
103
103104# REVERSE: __LA25Thunk_fpic:
104105# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2
105106# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>
106107# REVERSE-NEXT: 20058: 27 39 00 60 addiu $25, $25, 96
107108# REVERSE-NEXT: 2005c: 00 00 00 00 nop
109
108110# REVERSE: fpic:
109111# REVERSE-NEXT: 20060: 00 00 00 00 nop
110# REVERSE-NEXT: 20064: ef ef ef ef <unknown>
111# REVERSE-NEXT: 20068: ef ef ef ef <unknown>
112# REVERSE-NEXT: 2006c: ef ef ef ef <unknown>
112
113113# REVERSE: fnpic:
114114# REVERSE-NEXT: 20070: 00 00 00 00 nop
115# REVERSE-NEXT: Disassembly of section differentos:
115
116# REVERSE: Disassembly of section differentos:
116117# REVERSE-NEXT: __start:
117118# REVERSE-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
118119# REVERSE-NEXT: 20078: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic-script.s+29-85
......@@ -19,91 +19,28 @@
1919# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
2020# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
2121# CHECK-NEXT: 2000c: 00 00 00 00 nop
22
2223# CHECK: __LA25Thunk_foo1b:
2324# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
2425# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
2526# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
2627# CHECK-NEXT: 2001c: 00 00 00 00 nop
28
2729# CHECK: foo1a:
2830# CHECK-NEXT: 20020: 00 00 00 00 nop
31
2932# CHECK: foo1b:
3033# CHECK-NEXT: 20024: 00 00 00 00 nop
34
3135# CHECK: __LA25Thunk_foo2:
3236# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
3337# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
3438# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
3539# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
40
3841# CHECK: foo2:
3942# CHECK-NEXT: 20040: 00 00 00 00 nop
40# CHECK-NEXT: 20044: ef ef ef ef <unknown>
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>
43
10744# CHECK: __start:
10845# CHECK-NEXT: 20150: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
10946# CHECK-NEXT: 20154: 00 00 00 00 nop
......@@ -117,16 +54,16 @@
11754# CHECK-NEXT: 20174: 00 00 00 00 nop
11855# CHECK-NEXT: 20178: 0c 00 80 68 jal 131488 <fnpic>
11956# CHECK-NEXT: 2017c: 00 00 00 00 nop
57
12058# CHECK: __LA25Thunk_fpic:
12159# CHECK-NEXT: 20180: 3c 19 00 02 lui $25, 2
12260# CHECK-NEXT: 20184: 08 00 80 64 j 131472 <fpic>
12361# CHECK-NEXT: 20188: 27 39 01 90 addiu $25, $25, 400
12462# CHECK-NEXT: 2018c: 00 00 00 00 nop
63
12564# CHECK: fpic:
12665# CHECK-NEXT: 20190: 00 00 00 00 nop
127# CHECK-NEXT: 20194: ef ef ef ef <unknown>
128# CHECK-NEXT: 20198: ef ef ef ef <unknown>
129# CHECK-NEXT: 2019c: ef ef ef ef <unknown>
66
13067# CHECK: fnpic:
13168# CHECK-NEXT: 201a0: 00 00 00 00 nop
13269
......@@ -145,6 +82,7 @@ __start:
14582# RUN: echo "SECTIONS { .text 0x20000 : { *(.text) } }" > %t2.script
14683# RUN: ld.lld --script %t2.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t2.exe
14784# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s
85
14886# ORPH1: Disassembly of section .text:
14987# ORPH1-NEXT: __start:
15088# ORPH1-NEXT: 20000: 0c 00 80 15 jal 131156 <__LA25Thunk_foo1a>
......@@ -159,42 +97,43 @@ __start:
15997# ORPH1-NEXT: 20024: 00 00 00 00 nop
16098# ORPH1-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
16199# ORPH1-NEXT: 2002c: 00 00 00 00 nop
100
162101# ORPH1: __LA25Thunk_fpic:
163102# ORPH1-NEXT: 20030: 3c 19 00 02 lui $25, 2
164103# ORPH1-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
165104# ORPH1-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
166105# ORPH1-NEXT: 2003c: 00 00 00 00 nop
106
167107# ORPH1: fpic:
168108# ORPH1-NEXT: 20040: 00 00 00 00 nop
169# ORPH1-NEXT: 20044: ef ef ef ef <unknown>
170# ORPH1-NEXT: 20048: ef ef ef ef <unknown>
171# ORPH1-NEXT: 2004c: ef ef ef ef <unknown>
109
172110# ORPH1: fnpic:
173111# ORPH1-NEXT: 20050: 00 00 00 00 nop
112
174113# ORPH1: __LA25Thunk_foo1a:
175114# ORPH1-NEXT: 20054: 3c 19 00 02 lui $25, 2
176115# ORPH1-NEXT: 20058: 08 00 80 20 j 131200 <foo1a>
177116# ORPH1-NEXT: 2005c: 27 39 00 80 addiu $25, $25, 128
178117# ORPH1-NEXT: 20060: 00 00 00 00 nop
118
179119# ORPH1: __LA25Thunk_foo1b:
180120# ORPH1-NEXT: 20064: 3c 19 00 02 lui $25, 2
181121# ORPH1-NEXT: 20068: 08 00 80 21 j 131204 <foo1b>
182122# ORPH1-NEXT: 2006c: 27 39 00 84 addiu $25, $25, 132
183123# ORPH1-NEXT: 20070: 00 00 00 00 nop
184# ORPH1-NEXT: 20074: ef ef ef ef <unknown>
185# ORPH1-NEXT: 20078: ef ef ef ef <unknown>
186# ORPH1-NEXT: 2007c: ef ef ef ef <unknown>
124
187125# ORPH1: foo1a:
188126# ORPH1-NEXT: 20080: 00 00 00 00 nop
127
189128# ORPH1: foo1b:
190129# ORPH1-NEXT: 20084: 00 00 00 00 nop
130
191131# ORPH1: __LA25Thunk_foo2:
192132# ORPH1-NEXT: 20088: 3c 19 00 02 lui $25, 2
193133# ORPH1-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
194134# ORPH1-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
195135# ORPH1-NEXT: 20094: 00 00 00 00 nop
196# ORPH1-NEXT: 20098: ef ef ef ef <unknown>
197# ORPH1-NEXT: 2009c: ef ef ef ef <unknown>
136
198137# ORPH1: foo2:
199138# ORPH1-NEXT: 200a0: 00 00 00 00 nop
200139
......@@ -203,6 +142,7 @@ __start:
203142# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script
204143# RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe
205144# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s
145
206146# ORPH2: Disassembly of section .out:
207147# ORPH2-NEXT: __start:
208148# ORPH2-NEXT: 20000: 0c 00 80 18 jal 131168 <__LA25Thunk_foo1a>
......@@ -217,39 +157,43 @@ __start:
217157# ORPH2-NEXT: 20024: 00 00 00 00 nop
218158# ORPH2-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
219159# ORPH2-NEXT: 2002c: 00 00 00 00 nop
160
220161# ORPH2: __LA25Thunk_fpic:
221162# ORPH2-NEXT: 20030: 3c 19 00 02 lui $25, 2
222163# ORPH2-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
223164# ORPH2-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
224165# ORPH2-NEXT: 2003c: 00 00 00 00 nop
166
225167# ORPH2: fpic:
226168# ORPH2-NEXT: 20040: 00 00 00 00 nop
227# ORPH2-NEXT: 20044: ef ef ef ef <unknown>
228# ORPH2-NEXT: 20048: ef ef ef ef <unknown>
229# ORPH2-NEXT: 2004c: ef ef ef ef <unknown>
169
230170# ORPH2: fnpic:
231171# ORPH2-NEXT: 20050: 00 00 00 00 nop
232172# ORPH2-NEXT: Disassembly of section .text:
173
233174# ORPH2-NEXT: __LA25Thunk_foo1a:
234175# ORPH2-NEXT: 20060: 3c 19 00 02 lui $25, 2
235176# ORPH2-NEXT: 20064: 08 00 80 20 j 131200 <foo1a>
236177# ORPH2-NEXT: 20068: 27 39 00 80 addiu $25, $25, 128
237178# ORPH2-NEXT: 2006c: 00 00 00 00 nop
179
238180# ORPH2: __LA25Thunk_foo1b:
239181# ORPH2-NEXT: 20070: 3c 19 00 02 lui $25, 2
240182# ORPH2-NEXT: 20074: 08 00 80 21 j 131204 <foo1b>
241183# ORPH2-NEXT: 20078: 27 39 00 84 addiu $25, $25, 132
242184# ORPH2-NEXT: 2007c: 00 00 00 00 nop
185
243186# ORPH2: foo1a:
244187# ORPH2-NEXT: 20080: 00 00 00 00 nop
188
245189# ORPH2: foo1b:
246190# ORPH2-NEXT: 20084: 00 00 00 00 nop
191
247192# ORPH2: __LA25Thunk_foo2:
248193# ORPH2-NEXT: 20088: 3c 19 00 02 lui $25, 2
249194# ORPH2-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
250195# ORPH2-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
251196# ORPH2-NEXT: 20094: 00 00 00 00 nop
252# ORPH2-NEXT: 20098: ef ef ef ef <unknown>
253# ORPH2-NEXT: 2009c: ef ef ef ef <unknown>
197
254198# ORPH2: foo2:
255199# ORPH2-NEXT: 200a0: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic.s+9-16
......@@ -51,8 +51,6 @@
5151# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>
5252# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112
5353# 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
5755# CHECK: foo2:
5856# CHECK-NEXT: 20070: 00 00 00 00 nop
......@@ -62,15 +60,9 @@
6260# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>
6361# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144
6462# 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
6964# CHECK: fpic:
7065# 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
7567# CHECK: fnpic:
7668# CHECK-NEXT: 200a0: 00 00 00 00 nop
......@@ -87,27 +79,28 @@
8779# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
8880# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
8981# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82
9083# REVERSE: __LA25Thunk_foo1b:
9184# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
9285# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
9386# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
9487# REVERSE-NEXT: 2001c: 00 00 00 00 nop
88
9589# REVERSE: foo1a:
9690# REVERSE-NEXT: 20020: 00 00 00 00 nop
91
9792# REVERSE: foo1b:
9893# REVERSE-NEXT: 20024: 00 00 00 00 nop
94
9995# REVERSE: __LA25Thunk_foo2:
10096# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
10197# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
10298# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
10399# REVERSE-NEXT: 20034: 00 00 00 00 nop
104# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
105# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
100
106101# REVERSE: foo2:
107102# REVERSE-NEXT: 20040: 00 00 00 00 nop
108# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
109# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
110# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
103
111104# REVERSE: __start:
112105# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
113106# REVERSE-NEXT: 20054: 00 00 00 00 nop
......@@ -121,16 +114,16 @@
121114# REVERSE-NEXT: 20074: 00 00 00 00 nop
122115# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232 <fnpic>
123116# REVERSE-NEXT: 2007c: 00 00 00 00 nop
117
124118# REVERSE: __LA25Thunk_fpic:
125119# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2
126120# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic>
127121# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144
128122# REVERSE-NEXT: 2008c: 00 00 00 00 nop
123
129124# REVERSE: fpic:
130125# REVERSE-NEXT: 20090: 00 00 00 00 nop
131# REVERSE-NEXT: 20094: ef ef ef ef <unknown>
132# REVERSE-NEXT: 20098: ef ef ef ef <unknown>
133# REVERSE-NEXT: 2009c: ef ef ef ef <unknown>
126
134127# REVERSE: fnpic:
135128# REVERSE-NEXT: 200a0: 00 00 00 00 nop
136129
deps/lld/test/ELF/mips-sto-plt.s+2-2
......@@ -9,7 +9,7 @@
99# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
1010
1111# CHECK: Symbol {
12# CHECK: Name: foo0@
12# CHECK: Name: foo0
1313# CHECK-NEXT: Value: 0x0
1414# CHECK-NEXT: Size: 0
1515# CHECK-NEXT: Binding: Global
......@@ -18,7 +18,7 @@
1818# CHECK-NEXT: Section: Undefined
1919# CHECK-NEXT: }
2020# CHECK-NEXT: Symbol {
21# CHECK-NEXT: Name: foo1@
21# CHECK-NEXT: Name: foo1
2222# CHECK-NEXT: Value: 0x[[FOO1:[0-9A-F]+]]
2323# CHECK-NEXT: Size: 0
2424# CHECK-NEXT: Binding: Global
deps/lld/test/ELF/mips-tls-64.s+3-3
......@@ -28,9 +28,9 @@
2828# DIS-NEXT: 30040 00000000 00000001 00000000 00000000
2929# DIS-NEXT: 30050 00000000 00000001 ffffffff ffff8004
3030
31# DIS: 0000000000000000 l .tdata 00000000 loc
32# DIS: 0000000000000004 g .tdata 00000000 bar
33# DIS: 0000000000000000 g *UND* 00000000 foo
31# DIS: 0000000000000000 l O .tdata 00000000 loc
32# DIS: 0000000000000004 g O .tdata 00000000 bar
33# DIS: 0000000000000000 g O *UND* 00000000 foo
3434
3535# CHECK: Relocations [
3636# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-tls-hilo.s+1-1
......@@ -20,7 +20,7 @@
2020# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672
2121# %lo(loc0 - .tdata - 0x7000) --^
2222
23# DIS: 00000000 l .tdata 00000000 loc0
23# DIS: 00000000 l O .tdata 00000000 loc0
2424
2525# CHECK: Relocations [
2626# CHECK-NEXT: ]
deps/lld/test/ELF/mips-tls-static-64.s+2-2
......@@ -11,8 +11,8 @@
1111# CHECK-NEXT: 30010 ffff9004
1212#
1313# CHECK: SYMBOL TABLE:
14# CHECK: 0000000000020004 .text 00000000 __tls_get_addr
15# CHECK: 0000000000000000 g .tdata 00000000 tls1
14# CHECK: 0000000000020004 .text 00000000 __tls_get_addr
15# CHECK: 0000000000000000 g O .tdata 00000000 tls1
1616
1717 .text
1818 .global __start
deps/lld/test/ELF/mips-tls-static.s+2-2
......@@ -13,8 +13,8 @@
1313# CHECK-NEXT: 30020 ffff8000 00000001 00000000
1414#
1515# CHECK: SYMBOL TABLE:
16# CHECK: 0002000c .text 00000000 __tls_get_addr
17# CHECK: 00000000 g .tdata 00000000 tls1
16# CHECK: 0002000c .text 00000000 __tls_get_addr
17# CHECK: 00000000 g O .tdata 00000000 tls1
1818
1919 .text
2020 .global __start
deps/lld/test/ELF/mips-tls.s+3-3
......@@ -26,9 +26,9 @@
2626# DIS-NEXT: 30020 00000000 00000000 00000001 00000000
2727# DIS-NEXT: 30030 00000001 ffff8004
2828
29# DIS: 00000000 l .tdata 00000000 loc
30# DIS: 00000004 g .tdata 00000000 bar
31# DIS: 00000000 g *UND* 00000000 foo
29# DIS: 00000000 l O .tdata 00000000 loc
30# DIS: 00000004 g O .tdata 00000000 bar
31# DIS: 00000000 g O *UND* 00000000 foo
3232
3333# CHECK: Relocations [
3434# 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 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: rm -f %t.a
34// RUN: llvm-ar rcs %t.a %t.o
45// 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 @@
2020# ERR: unknown --oformat value: foo
2121
2222# RUN: ld.lld -o /dev/null %t --oformat elf
23# RUN: ld.lld -o /dev/null %t --oformat elf-foo
2324
2425.text
2526.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 @@
8585
8686// foo@plt
8787// Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 65536
88// DISASMDSO-EMPTY:
89// DISASMDSO-NEXT: foo@plt:
8890// DISASMDSO-NEXT: 10030: 90 00 00 90 adrp x16, #65536
8991// 0x3018 & 0xFFF = 0x18 = 24
9092// DISASMDSO-NEXT: 10034: 11 0e 40 f9 ldr x17, [x16, #24]
......@@ -93,6 +95,8 @@
9395
9496// bar@plt
9597// Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 65536
98// DISASMDSO-EMPTY:
99// DISASMDSO-NEXT: bar@plt:
96100// DISASMDSO-NEXT: 10040: 90 00 00 90 adrp x16, #65536
97101// 0x3020 & 0xFFF = 0x20 = 32
98102// DISASMDSO-NEXT: 10044: 11 12 40 f9 ldr x17, [x16, #32]
......@@ -101,6 +105,8 @@
101105
102106// weak@plt
103107// Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536
108// DISASMDSO-EMPTY:
109// DISASMDSO-NEXT: weak@plt:
104110// DISASMDSO-NEXT: 10050: 90 00 00 90 adrp x16, #65536
105111// 0x3028 & 0xFFF = 0x28 = 40
106112// DISASMDSO-NEXT: 10054: 11 16 40 f9 ldr x17, [x16, #40]
......@@ -113,7 +119,7 @@
113119// CHECKEXE-NEXT: SHF_ALLOC
114120// CHECKEXE-NEXT: SHF_EXECINSTR
115121// CHECKEXE-NEXT: ]
116// CHECKEXE-NEXT: Address: 0x20010
122// CHECKEXE-NEXT: Address: 0x210010
117123// CHECKEXE-NEXT: Offset:
118124// CHECKEXE-NEXT: Size: 64
119125// CHECKEXE-NEXT: Link:
......@@ -126,7 +132,7 @@
126132// CHECKEXE-NEXT: SHF_ALLOC
127133// CHECKEXE-NEXT: SHF_WRITE
128134// CHECKEXE-NEXT: ]
129// CHECKEXE-NEXT: Address: 0x30000
135// CHECKEXE-NEXT: Address: 0x220000
130136// CHECKEXE-NEXT: Offset:
131137// CHECKEXE-NEXT: Size: 40
132138// CHECKEXE-NEXT: Link:
......@@ -136,59 +142,63 @@
136142// CHECKEXE: Relocations [
137143// CHECKEXE-NEXT: Section ({{.*}}) .rela.plt {
138144
139// &(.got.plt[3]) = 0x30000 + 3 * 8 = 0x30018
140// CHECKEXE-NEXT: 0x30018 R_AARCH64_JUMP_SLOT bar 0x0
145// &(.got.plt[3]) = 0x220000 + 3 * 8 = 0x220018
146// CHECKEXE-NEXT: 0x220018 R_AARCH64_JUMP_SLOT bar 0x0
141147
142// &(.got.plt[4]) = 0x30000 + 4 * 8 = 0x30020
143// CHECKEXE-NEXT: 0x30020 R_AARCH64_JUMP_SLOT weak 0x0
148// &(.got.plt[4]) = 0x220000 + 4 * 8 = 0x220020
149// CHECKEXE-NEXT: 0x220020 R_AARCH64_JUMP_SLOT weak 0x0
144150// CHECKEXE-NEXT: }
145151// CHECKEXE-NEXT: ]
146152
147153// DUMPEXE: Contents of section .got.plt:
148154// .got.plt[0..2] = 0 (reserved)
149155// .got.plt[3..4] = .plt = 0x40010
150// DUMPEXE-NEXT: 30000 00000000 00000000 00000000 00000000 ................
151// DUMPEXE-NEXT: 30010 00000000 00000000 10000200 00000000 ................
152// DUMPEXE-NEXT: 30020 10000200 00000000 ........
156// DUMPEXE-NEXT: 220000 00000000 00000000 00000000 00000000
157// DUMPEXE-NEXT: 220010 00000000 00000000 10002100 00000000
158// DUMPEXE-NEXT: 220020 10002100 00000000
153159
154160// DISASMEXE: _start:
155// 0x2000c - 0x20000 = 0xc = 12
156// DISASMEXE-NEXT: 20000: 03 00 00 14 b #12
157// 0x20030 - 0x20004 = 0x2c = 44
158// DISASMEXE-NEXT: 20004: 0b 00 00 14 b #44
159// 0x20040 - 0x20008 = 0x38 = 56
160// DISASMEXE-NEXT: 20008: 0e 00 00 14 b #56
161// 0x21000c - 0x210000 = 0xc = 12
162// DISASMEXE-NEXT: 210000: 03 00 00 14 b #12
163// 0x210030 - 0x210004 = 0x2c = 44
164// DISASMEXE-NEXT: 210004: 0b 00 00 14 b #44
165// 0x210040 - 0x210008 = 0x38 = 56
166// DISASMEXE-NEXT: 210008: 0e 00 00 14 b #56
161167
162168// DISASMEXE: foo:
163// DISASMEXE-NEXT: 2000c: 1f 20 03 d5 nop
169// DISASMEXE-NEXT: 21000c: 1f 20 03 d5 nop
164170
165171// DISASMEXE: Disassembly of section .plt:
166172// DISASMEXE-NEXT: .plt:
167// DISASMEXE-NEXT: 20010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
168// &(.got.plt[2]) = 0x300B0 + 2 * 8 = 0x300C0
169// Page(0x30010) - Page(0x20014) = 0x30000 - 0x20000 = 0x10000 = 65536
170// DISASMEXE-NEXT: 20014: 90 00 00 90 adrp x16, #65536
173// DISASMEXE-NEXT: 210010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
174// &(.got.plt[2]) = 0x2200B0 + 2 * 8 = 0x2200C0
175// Page(0x220010) - Page(0x210014) = 0x220000 - 0x210000 = 0x10000 = 65536
176// DISASMEXE-NEXT: 210014: 90 00 00 90 adrp x16, #65536
171177// 0x120c0 & 0xFFF = 0xC0 = 192
172// DISASMEXE-NEXT: 20018: 11 0a 40 f9 ldr x17, [x16, #16]
173// DISASMEXE-NEXT: 2001c: 10 42 00 91 add x16, x16, #16
174// DISASMEXE-NEXT: 20020: 20 02 1f d6 br x17
175// DISASMEXE-NEXT: 20024: 1f 20 03 d5 nop
176// DISASMEXE-NEXT: 20028: 1f 20 03 d5 nop
177// DISASMEXE-NEXT: 2002c: 1f 20 03 d5 nop
178// DISASMEXE-NEXT: 210018: 11 0a 40 f9 ldr x17, [x16, #16]
179// DISASMEXE-NEXT: 21001c: 10 42 00 91 add x16, x16, #16
180// DISASMEXE-NEXT: 210020: 20 02 1f d6 br x17
181// DISASMEXE-NEXT: 210024: 1f 20 03 d5 nop
182// DISASMEXE-NEXT: 210028: 1f 20 03 d5 nop
183// DISASMEXE-NEXT: 21002c: 1f 20 03 d5 nop
178184
179185// bar@plt
180// Page(0x40018) - Page(0x20030) = 0x30000 - 0x20000 = 0x10000 = 65536
181// DISASMEXE-NEXT: 20030: 90 00 00 90 adrp x16, #65536
182// DISASMEXE-NEXT: 20034: 11 0e 40 f9 ldr x17, [x16, #24]
183// DISASMEXE-NEXT: 20038: 10 62 00 91 add x16, x16, #24
184// DISASMEXE-NEXT: 2003c: 20 02 1f d6 br x17
186// Page(0x40018) - Page(0x210030) = 0x220000 - 0x210000 = 0x10000 = 65536
187// DISASMEXE-EMPTY:
188// DISASMEXE-NEXT: bar@plt:
189// DISASMEXE-NEXT: 210030: 90 00 00 90 adrp x16, #65536
190// 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
186194// weak@plt
187// Page(0x40020) - Page(0x20040) = 0x30000 - 0x20000 = 0x10000 = 65536
188// DISASMEXE-NEXT: 20040: 90 00 00 90 adrp x16, #65536
189// DISASMEXE-NEXT: 20044: 11 12 40 f9 ldr x17, [x16, #32]
190// DISASMEXE-NEXT: 20048: 10 82 00 91 add x16, x16, #32
191// DISASMEXE-NEXT: 2004c: 20 02 1f d6 br x17
195// Page(0x40020) - Page(0x210040) = 0x220000 - 0x210000 = 0x10000 = 65536
196// DISASMEXE-EMPTY:
197// DISASMEXE-NEXT: weak@plt:
198// DISASMEXE-NEXT: 210040: 90 00 00 90 adrp x16, #65536
199// 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
193203.global _start,foo,bar
194204.weak weak
deps/lld/test/ELF/plt-i686.s+36-32
......@@ -17,7 +17,7 @@
1717// CHECK-NEXT: SHF_ALLOC
1818// CHECK-NEXT: SHF_EXECINSTR
1919// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x11020
20// CHECK-NEXT: Address: 0x401020
2121// CHECK-NEXT: Offset:
2222// CHECK-NEXT: Size: 48
2323// CHECK-NEXT: Link: 0
......@@ -30,7 +30,7 @@
3030// CHECK-NEXT: SHF_ALLOC
3131// CHECK-NEXT: SHF_WRITE
3232// CHECK-NEXT: ]
33// CHECK-NEXT: Address: 0x12000
33// CHECK-NEXT: Address: 0x402000
3434// CHECK-NEXT: Offset: 0x2000
3535// CHECK-NEXT: Size: 20
3636// CHECK-NEXT: Link: 0
......@@ -42,8 +42,8 @@
4242// 0x12000 + got.plt.reserved(12) + 4 = 0x12010
4343// CHECK: Relocations [
4444// CHECK-NEXT: Section ({{.*}}) .rel.plt {
45// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed 0x0
45// CHECK-NEXT: 0x40200C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x402010 R_386_JUMP_SLOT zed 0x0
4747// CHECK-NEXT: }
4848// CHECK-NEXT: ]
4949
......@@ -51,40 +51,44 @@
5151// values:
5252
5353// 16 is the size of PLT[0]
54// (0x11010 + 16) - (0x11000 + 1) - 4 = 27
55// (0x11010 + 16) - (0x11005 + 1) - 4 = 22
56// (0x11020 + 16) - (0x1100a + 1) - 4 = 33
54// (0x401010 + 16) - (0x401000 + 1) - 4 = 27
55// (0x401010 + 16) - (0x401005 + 1) - 4 = 22
56// (0x401020 + 16) - (0x40100a + 1) - 4 = 33
5757
5858// DISASM: local:
59// DISASM-NEXT: 11000: {{.*}}
60// DISASM-NEXT: 11002: {{.*}}
59// DISASM-NEXT: 401000: {{.*}}
60// DISASM-NEXT: 401002: {{.*}}
6161// DISASM: _start:
62// 0x11013 + 5 - 24 = 0x11000
63// DISASM-NEXT: 11004: e9 27 00 00 00 jmp 39
64// DISASM-NEXT: 11009: e9 22 00 00 00 jmp 34
65// DISASM-NEXT: 1100e: e9 2d 00 00 00 jmp 45
66// DISASM-NEXT: 11013: e9 e8 ff ff ff jmp -24
62// 0x401013 + 5 - 24 = 0x401000
63// DISASM-NEXT: 401004: e9 27 00 00 00 jmp 39
64// DISASM-NEXT: 401009: e9 22 00 00 00 jmp 34
65// DISASM-NEXT: 40100e: e9 2d 00 00 00 jmp 45
66// DISASM-NEXT: 401013: e9 e8 ff ff ff jmp -24
6767
68// 0x11010 - 0x1102b - 5 = -32
69// 0x11010 - 0x1103b - 5 = -48
70// 77828 = 0x13004 = .got.plt (0x13000) + 4
71// 77832 = 0x13008 = .got.plt (0x13000) + 8
72// 77836 = 0x1300C = .got.plt (0x13000) + got.plt.reserved(12)
73// 77840 = 0x13010 = .got.plt (0x13000) + got.plt.reserved(12) + 4
68// 0x401010 - 0x40102b - 5 = -32
69// 0x401010 - 0x40103b - 5 = -48
70// 4202500 = 0x402004 = .got.plt (0x402000) + 4
71// 4202504 = 0x402008 = .got.plt (0x402000) + 8
72// 4202508 = 0x40200C = .got.plt (0x402000) + got.plt.reserved(12)
73// 4202512 = 0x402010 = .got.plt (0x402000) + got.plt.reserved(12) + 4
7474// DISASM: Disassembly of section .plt:
7575// DISASM-NEXT: .plt:
76// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 73732
77// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *73736
78// DISASM-NEXT: 1102c: 90 nop
79// DISASM-NEXT: 1102d: 90 nop
80// DISASM-NEXT: 1102e: 90 nop
81// DISASM-NEXT: 1102f: 90 nop
82// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *73740
83// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $0
84// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>
85// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *73744
86// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $8
87// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>
76// DISASM-NEXT: 401020: ff 35 04 20 40 00 pushl 4202500
77// DISASM-NEXT: 401026: ff 25 08 20 40 00 jmpl *4202504
78// DISASM-NEXT: 40102c: 90 nop
79// DISASM-NEXT: 40102d: 90 nop
80// DISASM-NEXT: 40102e: 90 nop
81// DISASM-NEXT: 40102f: 90 nop
82// DISASM-EMPTY:
83// DISASM-NEXT: bar@plt:
84// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
85// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
86// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.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
8993// CHECKSHARED: Name: .plt
9094// CHECKSHARED-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/plt.s+10
......@@ -73,12 +73,18 @@
7373// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
7474// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
7575// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
76// DISASM-EMPTY:
77// DISASM-NEXT: bar@plt:
7678// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
7779// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
7880// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
81// DISASM-EMPTY:
82// DISASM-NEXT: zed@plt:
7983// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
8084// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
8185// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
86// DISASM-EMPTY:
87// DISASM-NEXT: _start@plt:
8288// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
8389// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2
8490// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <.plt>
......@@ -102,9 +108,13 @@
102108// DISASM2-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
103109// DISASM2-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
104110// DISASM2-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
111// DISASM2-EMPTY:
112// DISASM2-NEXT: bar@plt:
105113// DISASM2-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
106114// DISASM2-NEXT: 201036: 68 00 00 00 00 pushq $0
107115// DISASM2-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
116// DISASM2-EMPTY:
117// DISASM2-NEXT: zed@plt:
108118// DISASM2-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
109119// DISASM2-NEXT: 201046: 68 01 00 00 00 pushq $1
110120// 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:
5555# CHECK: .FR_PPC_REL24:
5656# 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
5869.section .R_PPC_REL32,"ax",@progbits
5970.globl .FR_PPC_REL32
6071.FR_PPC_REL32:
......@@ -64,7 +75,7 @@ mystr:
6475
6576# CHECK: Disassembly of section .R_PPC_REL32:
6677# CHECK: .FR_PPC_REL32:
67# CHECK: 11020: 00 00 00 04
78# CHECK: 11024: 00 00 00 04
6879
6980.section .R_PPC_ADDR32,"ax",@progbits
7081.globl .FR_PPC_ADDR32
......@@ -75,7 +86,7 @@ mystr:
7586
7687# CHECK: Disassembly of section .R_PPC_ADDR32:
7788# CHECK: .FR_PPC_ADDR32:
78# CHECK: 11024: 00 01 10 28
89# CHECK: 11028: 00 01 10 2c
7990
8091.align 2
8192.section .R_PPC_PLTREL24,"ax",@progbits
......@@ -87,4 +98,4 @@ mystr:
8798
8899# CHECK: Disassembly of section .R_PPC_PLTREL24:
89100# CHECK: .R_PPC_PLTREL24:
90# CHECK: 11028: 48 00 00 04 b .+4
101# 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 @@
22
33// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
44// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
77// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
88// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %s
99
1010// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1111// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
1414// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
1515// 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:
7575// CHECK: foo_external_diff:
7676// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2
7777// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640
78// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 0
78// CHECK-NEXT: 10010088: {{.*}} nop
7979// CHECK: foo_external_same:
8080// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3
deps/lld/test/ELF/ppc64-gd-to-ie.s+4-4
......@@ -5,16 +5,16 @@
55# RUN: ld.lld -shared %t2.o -o %t3.so
66# RUN: ld.lld %t.o %t3.so -o %t
77# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
8# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
9# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
8# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
9# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1010
1111# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1212# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
1313# RUN: ld.lld -shared %t2.o -o %t3.so
1414# RUN: ld.lld %t.o %t3.so -o %t
1515# RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
16# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
17# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
16# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
17# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1818
1919 .text
2020 .abiversion 2
deps/lld/test/ELF/ppc64-general-dynamic-tls.s+6-6
......@@ -2,17 +2,17 @@
22
33// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
44// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
77// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
99
1010// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1111// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
1414// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
1616
1717 .text
1818 .abiversion 2
deps/lld/test/ELF/ppc64-got-indirect.s+2-2
......@@ -83,8 +83,8 @@ glob:
8383# CHECK: _start:
8484# CHECK-NEXT: 10010000: {{.*}} addis 2, 12, 3
8585# CHECK-NEXT: 10010004: {{.*}} addi 2, 2, -32768
86# CHECK-NEXT: 10010008: {{.*}} addis 3, 2, 0
87# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(3)
86# CHECK-NEXT: 10010008: {{.*}} nop
87# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(2)
8888# CHECK: 1001001c: {{.*}} lwa 3, 0(3)
8989
9090# 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 @@
44// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
55// RUN: ld.lld -shared %t2.o -o %t2.so
66// 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 %s
8// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
8// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
99// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
10// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
10// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
1111
1212// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1313// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
1414// RUN: ld.lld -shared %t2.o -o %t2.so
1515// 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 %s
17// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
16// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
17// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1818// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
19// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
19// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
2020
2121 .text
2222 .abiversion 2
deps/lld/test/ELF/ppc64-local-dynamic.s+6-6
......@@ -2,17 +2,17 @@
22
33// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
44// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
77// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
99
1010// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1111// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
1414// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
1616
1717 .text
1818 .abiversion 2
deps/lld/test/ELF/ppc64-local-exec-tls.s+2-2
......@@ -1,8 +1,8 @@
11// REQUIRES: ppc
22// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
66
77 .text
88 .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 @@
11// REQUIRES: ppc
22
33// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared -z notext %t.o -o %t.so
4// RUN: ld.lld -shared %t.o -o %t.so
55// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
66
77// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
8// RUN: ld.lld -shared -z notext %t.o -o %t.so
8// RUN: ld.lld -shared %t.o -o %t.so
99// 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:
6363
6464# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
6565# CHECK: .FR_PPC64_TOC16_HA:
66# CHECK: 10010018: {{.*}} addis 1, 2, 0
66# CHECK: 10010018: {{.*}} nop
6767
6868.section .R_PPC64_REL24,"ax",@progbits
6969.globl .FR_PPC64_REL24
......@@ -76,6 +76,17 @@ _start:
7676# CHECK: .FR_PPC64_REL24:
7777# 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
7990.section .R_PPC64_ADDR16_LO,"ax",@progbits
8091.globl .FR_PPC64_ADDR16_LO
8192.FR_PPC64_ADDR16_LO:
......@@ -83,7 +94,7 @@ _start:
8394
8495# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
8596# CHECK: .FR_PPC64_ADDR16_LO:
86# CHECK: 10010020: {{.*}} li 1, 0
97# CHECK: 10010024: {{.*}} li 1, 0
8798
8899.section .R_PPC64_ADDR16_HI,"ax",@progbits
89100.globl .FR_PPC64_ADDR16_HI
......@@ -92,7 +103,7 @@ _start:
92103
93104# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
94105# CHECK: .FR_PPC64_ADDR16_HI:
95# CHECK: 10010024: {{.*}} li 1, 4097
106# CHECK: 10010028: {{.*}} li 1, 4097
96107
97108.section .R_PPC64_ADDR16_HA,"ax",@progbits
98109.globl .FR_PPC64_ADDR16_HA
......@@ -101,7 +112,7 @@ _start:
101112
102113# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
103114# CHECK: .FR_PPC64_ADDR16_HA:
104# CHECK: 10010028: {{.*}} li 1, 4097
115# CHECK: 1001002c: {{.*}} li 1, 4097
105116
106117.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
107118.globl .FR_PPC64_ADDR16_HIGHER
......@@ -110,7 +121,7 @@ _start:
110121
111122# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
112123# CHECK: .FR_PPC64_ADDR16_HIGHER:
113# CHECK: 1001002c: {{.*}} li 1, 0
124# CHECK: 10010030: {{.*}} li 1, 0
114125
115126.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
116127.globl .FR_PPC64_ADDR16_HIGHERA
......@@ -119,7 +130,7 @@ _start:
119130
120131# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
121132# CHECK: .FR_PPC64_ADDR16_HIGHERA:
122# CHECK: 10010030: {{.*}} li 1, 0
133# CHECK: 10010034: {{.*}} li 1, 0
123134
124135.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
125136.globl .FR_PPC64_ADDR16_HIGHEST
......@@ -128,7 +139,7 @@ _start:
128139
129140# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
130141# CHECK: .FR_PPC64_ADDR16_HIGHEST:
131# CHECK: 10010034: {{.*}} li 1, 0
142# CHECK: 10010038: {{.*}} li 1, 0
132143
133144.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
134145.globl .FR_PPC64_ADDR16_HIGHESTA
......@@ -137,7 +148,7 @@ _start:
137148
138149# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
139150# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
140# CHECK: 10010038: {{.*}} li 1, 0
151# CHECK: 1001003c: {{.*}} li 1, 0
141152
142153.section .R_PPC64_REL32, "ax",@progbits
143154.globl .FR_PPC64_REL32
......@@ -149,20 +160,20 @@ _start:
149160
150161# DATALE: Disassembly of section .rodata:
151162# DATALE: .rodata:
152# DATALE: 10000190: b4 fe 00 00
163# DATALE: 10000190: b8 fe 00 00
153164
154165# DATABE: Disassembly of section .rodata:
155166# DATABE: .rodata:
156# DATABE: 10000190: 00 00 fe b4
167# DATABE: 10000190: 00 00 fe b8
157168
158169# Address of rodata + value stored at rodata entry
159170# should equal address of LBB0_2.
160171# 0x10000190 + 0xfeb4 = 0x10010044
161172# CHECK: Disassembly of section .R_PPC64_REL32:
162173# CHECK: .FR_PPC64_REL32:
163# CHECK: 1001003c: {{.*}} addis 5, 2, 0
164# CHECK: 10010040: {{.*}} ld 5, -32736(5)
165# CHECK: 10010044: {{.*}} add 3, 3, 4
174# CHECK: 10010040: {{.*}} nop
175# CHECK: 10010044: {{.*}} ld 5, -32736(2)
176# CHECK: 10010048: {{.*}} add 3, 3, 4
166177
167178.section .R_PPC64_REL64, "ax",@progbits
168179.globl .FR_PPC64_REL64
......@@ -178,16 +189,16 @@ __foo:
178189
179190# Check that address of eh_frame entry + value stored
180191# should equal the address of foo. Since it is not aligned,
181# the entry is not stored exactly at 100001a8. It starts at
182# address 0x100001aa and has the value 0xfeaa.
183# 0x100001aa + 0xfeaa = 0x10010054
192# the entry is not stored exactly at 10000198. It starts at
193# address 0x1000019a and has the value 0xfeaa.
194# 0x100001aa + 0xfeae = 0x10010058
184195# DATALE: Disassembly of section .eh_frame:
185196# DATALE: .eh_frame:
186# DATALE: 100001a8: {{.*}} aa fe
197# DATALE: 100001a8: {{.*}} ae fe
187198
188199# DATABE: Disassembly of section .eh_frame:
189200# DATABE: .eh_frame:
190# DATABE: 100001b0: fe aa {{.*}}
201# DATABE: 100001b0: fe ae {{.*}}
191202
192203# CHECK: __foo
193# CHECK-NEXT: 10010054: {{.*}} li 3, 0
204# 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 @@
11// REQUIRES: ppc
22
33// 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
4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
55// RUN: ld.lld %t.o -o %t
6// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
88
99// 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 %s
10// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
1111// RUN: ld.lld %t.o -o %t
12// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
12// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1414
1515 .text
1616 .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 @@
11// REQUIRES: ppc
22
33// 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
4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
55// RUN: ld.lld %t.o -o %t
6// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
88
99// 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 %s
10// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
1111// RUN: ld.lld %t.o -o %t
12// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
12// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1414
1515 .text
1616 .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 @@
11# REQUIRES: ppc
22
33# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS %s
4# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-LE %s
55# RUN: ld.lld %t.o -o %t2
66# RUN: llvm-objdump -D %t2 | FileCheck %s
7# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %s
78
89# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
910# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
1011# RUN: ld.lld %t.o -o %t2
12# RUN: llvm-objdump -D %t2 | FileCheck %s
1113# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
1214
1315# Make sure we calculate the offset correctly for a toc-relative access to a
......@@ -45,15 +47,15 @@ _start:
4547
4648# Verify the relocations that get emitted for the global variable are the
4749# expected ones.
48# RELOCS: Relocations [
49# RELOCS-NEXT: .rela.text {
50# RELOCS: 0x8 R_PPC64_TOC16_HA global_a 0x0
51# RELOCS: 0xC R_PPC64_TOC16_LO global_a 0x0
50# RELOCS-LE: Relocations [
51# RELOCS-LE-NEXT: .rela.text {
52# RELOCS-LE: 0x8 R_PPC64_TOC16_HA global_a 0x0
53# RELOCS-LE: 0xC R_PPC64_TOC16_LO global_a 0x0
5254
5355# RELOCS-BE: Relocations [
5456# RELOCS-BE-NEXT: .rela.text {
5557# RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x0
56# RELOCS-NE: 0xE R_PPC64_TOC16_LO global_a 0x0
58# RELOCS-BE: 0xE R_PPC64_TOC16_LO global_a 0x0
5759
5860# Want to check _start for the values used to build the offset from the TOC base
5961# to global_a. The .TOC. symbol is expected at address 0x10030000, and the
......@@ -70,19 +72,9 @@ _start:
7072# CHECK-NEXT: global_a:
7173# CHECK-NEXT: 10020000: {{.*}}
7274
73# CHECK: Disassembly of section .got:
74# CHECK-NEXT: .got:
75# CHECK-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: {{.*}}
75# CHECK-LE: Disassembly of section .got:
76# CHECK-LE-NEXT: .got:
77# CHECK-LE-NEXT: 10030000: 00 80 03 10
8678
8779# CHECK-BE: Disassembly of section .got:
8880# 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:
2222 blr
2323
2424# 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.
2626.global _start
2727_start:
2828 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 @@
33# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
44# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t
55# RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM
6# RUN: llvm-readelf %t -t | FileCheck %s --check-prefix=SYM
6# RUN: llvm-readelf %t --symbols | FileCheck %s --check-prefix=SYM
77
88# It would be much easier to understand/read this test if llvm-objdump would print
99# the immediates in hex.
deps/lld/test/ELF/progname.s+1-1
......@@ -17,7 +17,7 @@
1717// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
1818// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
1919
20// CHECK: Name: __progname@
20// CHECK: Name: __progname
2121// CHECK-NEXT: Value: 0x201000
2222// CHECK-NEXT: Size: 0
2323// CHECK-NEXT: Binding: Global (0x1)
deps/lld/test/ELF/protected-shared.s+2-2
......@@ -32,7 +32,7 @@ bar:
3232
3333// CHECK: DynamicSymbols [
3434// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name: @
35// CHECK-NEXT: Name:
3636// CHECK-NEXT: Value: 0x0
3737// CHECK-NEXT: Size: 0
3838// CHECK-NEXT: Binding: Local (0x0)
......@@ -41,7 +41,7 @@ bar:
4141// CHECK-NEXT: Section: Undefined (0x0)
4242// CHECK-NEXT: }
4343// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: foo@
44// CHECK-NEXT: Name: foo
4545// CHECK-NEXT: Value: 0x0
4646// CHECK-NEXT: Size: 0
4747// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/push-state.s+3
......@@ -32,5 +32,8 @@
3232// RUN: ld.lld -o %t.exe -L%t.dir -push-state -static -pop-state %t1.o -lfoo
3333// 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
3538.globl _start
3639_start:
deps/lld/test/ELF/relative-dynamic-reloc-ppc64.s+2-2
......@@ -32,7 +32,7 @@
3232
3333// CHECK: DynamicSymbols [
3434// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name: @
35// CHECK-NEXT: Name:
3636// CHECK-NEXT: Value: 0x0
3737// CHECK-NEXT: Size: 0
3838// CHECK-NEXT: Binding: Local
......@@ -41,7 +41,7 @@
4141// CHECK-NEXT: Section: Undefined
4242// CHECK-NEXT: }
4343// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: external@
44// CHECK-NEXT: Name: external
4545// CHECK-NEXT: Value: 0x0
4646// CHECK-NEXT: Size: 0
4747// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/relative-dynamic-reloc.s+2-2
......@@ -28,7 +28,7 @@
2828
2929// CHECK: DynamicSymbols [
3030// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name: @
31// CHECK-NEXT: Name:
3232// CHECK-NEXT: Value: 0x0
3333// CHECK-NEXT: Size: 0
3434// CHECK-NEXT: Binding: Local
......@@ -37,7 +37,7 @@
3737// CHECK-NEXT: Section: Undefined
3838// CHECK-NEXT: }
3939// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: external@
40// CHECK-NEXT: Name: external
4141// CHECK-NEXT: Value: 0x0
4242// CHECK-NEXT: Size: 0
4343// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/relocatable-bss.s+1-1
......@@ -20,7 +20,7 @@
2020# CHECK-NEXT: Version:
2121# CHECK-NEXT: Entry:
2222# CHECK-NEXT: ProgramHeaderOffset:
23# CHECK-NEXT: SectionHeaderOffset: 0xD8
23# CHECK-NEXT: SectionHeaderOffset: 0xE8
2424# CHECK-NEXT: Flags [
2525# CHECK-NEXT: ]
2626# CHECK-NEXT: HeaderSize:
deps/lld/test/ELF/relocatable-comdat-multiple.s+2-2
......@@ -8,7 +8,7 @@
88# CHECK-NEXT: Group {
99# CHECK-NEXT: Name: .group
1010# CHECK-NEXT: Index: 2
11# CHECK-NEXT: Link: 8
11# CHECK-NEXT: Link: 9
1212# CHECK-NEXT: Info: 1
1313# CHECK-NEXT: Type: COMDAT
1414# CHECK-NEXT: Signature: aaa
......@@ -20,7 +20,7 @@
2020# CHECK-NEXT: Group {
2121# CHECK-NEXT: Name: .group
2222# CHECK-NEXT: Index: 5
23# CHECK-NEXT: Link: 8
23# CHECK-NEXT: Link: 9
2424# CHECK-NEXT: Info: 6
2525# CHECK-NEXT: Type: COMDAT
2626# CHECK-NEXT: Signature: bbb
deps/lld/test/ELF/relocatable-comdat.s+1-1
......@@ -30,7 +30,7 @@
3030# CHECK-NEXT: Group {
3131# CHECK-NEXT: Name: .group
3232# CHECK-NEXT: Index: 2
33# CHECK-NEXT: Link: 5
33# CHECK-NEXT: Link: 6
3434# CHECK-NEXT: Info: 1
3535# CHECK-NEXT: Type: COMDAT
3636# CHECK-NEXT: Signature: abc
deps/lld/test/ELF/relocatable-comdat2.s+2-2
......@@ -13,7 +13,7 @@
1313# CHECK-NEXT: Group {
1414# CHECK-NEXT: Name: .group
1515# CHECK-NEXT: Index: 2
16# CHECK-NEXT: Link: 7
16# CHECK-NEXT: Link: 8
1717# CHECK-NEXT: Info: 1
1818# CHECK-NEXT: Type: COMDAT
1919# CHECK-NEXT: Signature: bar
......@@ -24,7 +24,7 @@
2424# CHECK-NEXT: Group {
2525# CHECK-NEXT: Name: .group
2626# CHECK-NEXT: Index: 4
27# CHECK-NEXT: Link: 7
27# CHECK-NEXT: Link: 8
2828# CHECK-NEXT: Info: 2
2929# CHECK-NEXT: Type: COMDAT
3030# CHECK-NEXT: Signature: zed
deps/lld/test/ELF/relocatable-compressed-input.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: ld.lld %t1 -o %t2 -r
88# 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.
1111# CHECK: Section {
1212# CHECK: Index:
1313# CHECK: Name: .debug_str
deps/lld/test/ELF/relocatable-many-sections.s+10-8
......@@ -9,8 +9,8 @@
99## sections amount is greater than SHN_LORESERVE.
1010# RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR
1111# HDR: ElfHeader {
12# HDR: SectionHeaderCount: 0 (65543)
13# HDR-NEXT: StringTableSectionIndex: 65535 (65541)
12# HDR: SectionHeaderCount: 0 (65544)
13# HDR-NEXT: StringTableSectionIndex: 65535 (65542)
1414
1515## Check that:
1616## 1) 65541 is the index of .shstrtab section.
......@@ -18,13 +18,15 @@
1818## 3) .symtab_shndxr entry size and alignment == 4.
1919## 4) .symtab_shndxr has size equal to
2020## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c
21
2122# RUN: llvm-readelf -sections -symbols %t | FileCheck %s
22## [Nr] Name Type Address Off Size ES Flg Lk Inf Al
23# CHECK: [65538] .bar
24# CHECK-NEXT: [65539] .symtab SYMTAB 0000000000000000 000040 180078 18 65542 65539 8
25# CHECK-NEXT: [65540] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65539 0 4
26# CHECK-NEXT: [65541] .shstrtab STRTAB 0000000000000000 1c00cc 0f0035 00 0 0 1
27# CHECK-NEXT: [65542] .strtab STRTAB 0000000000000000 2b0101 00000c 00
23# [Nr] Name Type Address Off Size ES Flg Lk Inf Al
24# CHECK: [65539] .note.GNU-stack PROGBITS 0000000000000000 000040 000000 00 0 0 1
25# CHECK: [65540] .symtab SYMTAB 0000000000000000 000040 180078 18 65543 65539 8
26# CHECK: [65541] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65540 0 4
27# CHECK: [65542] .shstrtab STRTAB 0000000000000000 1c00cc 0f0045 00 0 0 1
28# CHECK: [65543] .strtab STRTAB 0000000000000000 2b0111 00000c 00 0 0 1
29
2830# 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE).
2931# 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 @@
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o
55# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
66# 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
78# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
89
910## Test --relocatable alias
......@@ -37,8 +38,8 @@
3738# CHECK-NEXT: ProgramHeaderEntrySize: 0
3839# CHECK-NEXT: ProgramHeaderCount: 0
3940# CHECK-NEXT: SectionHeaderEntrySize: 64
40# CHECK-NEXT: SectionHeaderCount: 7
41# CHECK-NEXT: StringTableSectionIndex: 5
41# CHECK-NEXT: SectionHeaderCount: 8
42# CHECK-NEXT: StringTableSectionIndex: 6
4243# CHECK-NEXT: }
4344
4445# CHECK: Relocations [
......@@ -51,6 +52,17 @@
5152# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0
5253# 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
5466# CHECKTEXT: Disassembly of section .text:
5567# CHECKTEXT-NEXT: main:
5668# 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 @@
99
1010# CHECK: Disassembly of section .text:
1111# CHECK-NEXT: foo:
12# CHECK-NEXT: 20000: 01 00 00 14 b #4
12# CHECK-NEXT: 210000: 01 00 00 14 b #4
1313# CHECK: bar:
14# CHECK-NEXT: 20004: ff ff ff 17 b #-4
14# CHECK-NEXT: 210004: ff ff ff 17 b #-4
1515
1616!ELF
1717FileHeader:
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// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: llvm-objdump -t -d %tout | FileCheck %s
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -t -d %t | FileCheck %s
55
66.global _start
77_start:
......@@ -10,5 +10,5 @@ _start:
1010.global sym1
1111.comm sym1,4,4
1212
13// CHECK: 201000: {{.*}} movl $1, 4086(%rip)
14// CHECK: 0000000000202000 g .bss 00000004 sym1
13# CHECK: 201000: {{.*}} movl $1, 4086(%rip)
14# CHECK: 0000000000202000 g O .bss 00000004 sym1
deps/lld/test/ELF/relocation-copy-i686.s+7-7
......@@ -21,7 +21,7 @@ movl $9, z
2121// CHECK-NEXT: SHF_ALLOC
2222// CHECK-NEXT: SHF_WRITE
2323// CHECK-NEXT: ]
24// CHECK-NEXT: Address: 0x13000
24// CHECK-NEXT: Address: 0x403000
2525// CHECK-NEXT: Offset:
2626// CHECK-NEXT: Size: 24
2727// CHECK-NEXT: Link: 0
......@@ -52,12 +52,12 @@ movl $9, z
5252// CHECK-NEXT: }
5353// CHECK-NEXT: ]
5454
55// 77824 = 0x13000
55// 4206592 = 0x403000
5656// 16 is alignment here
57// 77840 = 0x13000 + 16
58// 77844 = 0x13000 + 16 + 4
57// 4206608 = 0x403000 + 16
58// 4206612 = 0x403000 + 16 + 4
5959// CODE: Disassembly of section .text:
6060// CODE-NEXT: main:
61// CODE-NEXT: 11000: c7 05 00 30 01 00 05 00 00 00 movl $5, 77824
62// CODE-NEXT: 1100a: c7 05 10 30 01 00 07 00 00 00 movl $7, 77840
63// CODE-NEXT: 11014: c7 05 14 30 01 00 09 00 00 00 movl $9, 77844
61// CODE-NEXT: 401000: c7 05 00 30 40 00 05 00 00 00 movl $5, 4206592
62// CODE-NEXT: 40100a: c7 05 10 30 40 00 07 00 00 00 movl $7, 4206608
63// 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:
2727
2828// CHECK: Disassembly of section .R_386_32:
2929// CHECK-NEXT: R_386_32:
30// CHECK-NEXT: 11000: {{.*}} movl $69633, %edx
30// CHECK-NEXT: 401000: {{.*}} movl $4198401, %edx
3131
3232// CHECK: Disassembly of section .R_386_PC32:
3333// CHECK-NEXT: R_386_PC32:
34// CHECK-NEXT: 11005: e8 04 00 00 00 calll 4
34// CHECK-NEXT: 401005: e8 04 00 00 00 calll 4
3535
3636// CHECK: R_386_PC32_2:
37// CHECK-NEXT: 1100e: 90 nop
37// CHECK-NEXT: 40100e: 90 nop
3838
3939// Create a .got
4040movl bar@GOT, %eax
......@@ -45,7 +45,7 @@ movl bar@GOT, %eax
4545// ADDR-NEXT: SHF_ALLOC
4646// ADDR-NEXT: SHF_EXECINSTR
4747// ADDR-NEXT: ]
48// ADDR-NEXT: Address: 0x11040
48// ADDR-NEXT: Address: 0x401040
4949// ADDR-NEXT: Offset: 0x1040
5050// ADDR-NEXT: Size: 32
5151
......@@ -55,7 +55,7 @@ movl bar@GOT, %eax
5555// ADDR-NEXT: SHF_ALLOC
5656// ADDR-NEXT: SHF_WRITE
5757// ADDR-NEXT: ]
58// ADDR-NEXT: Address: 0x13078
58// ADDR-NEXT: Address: 0x403078
5959// ADDR-NEXT: Offset:
6060// ADDR-NEXT: Size: 8
6161
......@@ -63,18 +63,18 @@ movl bar@GOT, %eax
6363R_386_GOTPC:
6464 movl $_GLOBAL_OFFSET_TABLE_, %eax
6565
66// 0x12078 + 8 - 0x11014 = 4204
66// 0x402078 + 8 - 0x401014 = 4204
6767
6868// CHECK: Disassembly of section .R_386_GOTPC:
6969// CHECK-NEXT: R_386_GOTPC:
70// CHECK-NEXT: 11014: {{.*}} movl $8300, %eax
70// CHECK-NEXT: 401014: {{.*}} movl $8300, %eax
7171
7272.section .dynamic_reloc, "ax",@progbits
7373 call bar
74// addr(.plt) + 16 - (0x11019 + 5) = 50
74// addr(.plt) + 16 - (0x401019 + 5) = 50
7575// CHECK: Disassembly of section .dynamic_reloc:
7676// CHECK-NEXT: .dynamic_reloc:
77// CHECK-NEXT: 11019: e8 32 00 00 00 calll 50
77// CHECK-NEXT: 401019: e8 32 00 00 00 calll 50
7878
7979.section .R_386_GOT32,"ax",@progbits
8080.global R_386_GOT32
......@@ -84,13 +84,13 @@ R_386_GOT32:
8484 movl bar+8@GOT, %eax
8585 movl zed+4@GOT, %eax
8686
87// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)
88// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)
87// 4294967288 = 0xFFFFFFF8 = got[0](0x402070) - .got(0x402070) - sizeof(.got)(8)
88// 4294967292 = 0xFFFFFFFC = got[1](0x402074) - .got(0x402070) - sizeof(.got)(8)
8989// 0xFFFFFFF8 + 8 = 0
9090// 0xFFFFFFFC + 4 = 0
9191// CHECK: Disassembly of section .R_386_GOT32:
9292// CHECK-NEXT: R_386_GOT32:
93// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax
94// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax
95// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax
96// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax
93// CHECK-NEXT: 40101e: a1 f8 ff ff ff movl 4294967288, %eax
94// CHECK-NEXT: 401023: a1 fc ff ff ff movl 4294967292, %eax
95// CHECK-NEXT: 401028: a1 00 00 00 00 movl 0, %eax
96// 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 @@
11// REQUIRES: x86
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
33// 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 section
4// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): offset is outside the section
55
66.data
77.long .foo + 10
deps/lld/test/ELF/relocation-size-shared.s+1-14
......@@ -28,20 +28,7 @@
2828// DISASM-NEXT: 20100c: 00 00
2929// DISASM-NEXT: 20100e: 00 00
3030// DISASM-NEXT: 201010: 1b 00
31// DISASM-NEXT: 201012: 00 00
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
31// DISASM-NEXT: ...
4532// DISASM-NEXT: 20102e: 00 00
4633// DISASM: _start:
4734// 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 @@
5757
5858// DISASMSHARED: Disassembly of section test:
5959// DISASMSHARED-NEXT: _data:
60// DISASMSHARED-NEXT: 1000: 00 00
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
60// DISASMSHARED-NEXT: ...
7261// DISASMSHARED-NEXT: 1018: 19 00
7362// DISASMSHARED-NEXT: 101a: 00 00
7463// DISASMSHARED-NEXT: 101c: 00 00
deps/lld/test/ELF/reproduce-backslash.s+1-1
......@@ -6,4 +6,4 @@
66# RUN: ld.lld %T/foo\\.o --reproduce %T/repro.tar -o /dev/null
77# RUN: tar tf %T/repro.tar | FileCheck %s
88
9# CHECK: repro/{{.*}}/foo\\.o
9# CHECK: repro/{{.*}}/foo\{{[\]?}}.o
deps/lld/test/ELF/retain-symbols-file.s+1-1
......@@ -11,7 +11,7 @@
1111
1212# CHECK: DynamicSymbols [
1313# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Name: @
14# CHECK-NEXT: Name:
1515# CHECK-NEXT: Value:
1616# CHECK-NEXT: Size:
1717# 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 @@
141141// CHECK-NEXT: }
142142// CHECK-NEXT: Symbol {
143143// CHECK-NEXT: Name: _DYNAMIC
144// CHECK-NEXT: Value: 0x12000
144// CHECK-NEXT: Value: 0x402000
145145// CHECK-NEXT: Size: 0
146146// CHECK-NEXT: Binding: Local
147147// CHECK-NEXT: Type: None
......@@ -152,7 +152,7 @@
152152// CHECK-NEXT: }
153153// CHECK-NEXT: Symbol {
154154// CHECK-NEXT: Name: _start
155// CHECK-NEXT: Value: 0x11000
155// CHECK-NEXT: Value: 0x401000
156156// CHECK-NEXT: Size: 0
157157// CHECK-NEXT: Binding: Global
158158// CHECK-NEXT: Type: None
......@@ -181,7 +181,7 @@
181181
182182// CHECK: DynamicSymbols [
183183// CHECK-NEXT: Symbol {
184// CHECK-NEXT: Name: @
184// CHECK-NEXT: Name:
185185// CHECK-NEXT: Value: 0x0
186186// CHECK-NEXT: Size: 0
187187// CHECK-NEXT: Binding: Local
......@@ -190,8 +190,8 @@
190190// CHECK-NEXT: Section: Undefined
191191// CHECK-NEXT: }
192192// CHECK-NEXT: Symbol {
193// CHECK-NEXT: Name: _start@
194// CHECK-NEXT: Value: 0x11000
193// CHECK-NEXT: Name: _start
194// CHECK-NEXT: Value: 0x401000
195195// CHECK-NEXT: Size: 0
196196// CHECK-NEXT: Binding: Global
197197// CHECK-NEXT: Type: Non
......@@ -199,7 +199,7 @@
199199// CHECK-NEXT: Section: .text
200200// CHECK-NEXT: }
201201// CHECK-NEXT: Symbol {
202// CHECK-NEXT: Name: bar@
202// CHECK-NEXT: Name: bar
203203// CHECK-NEXT: Value: 0x0
204204// CHECK-NEXT: Size: 0
205205// CHECK-NEXT: Binding: Global
......@@ -208,7 +208,7 @@
208208// CHECK-NEXT: Section: Undefined
209209// CHECK-NEXT: }
210210// CHECK-NEXT: Symbol {
211// CHECK-NEXT: Name: zed@
211// CHECK-NEXT: Name: zed
212212// CHECK-NEXT: Value: 0x0
213213// CHECK-NEXT: Size: 0
214214// CHECK-NEXT: Binding: Global
......@@ -220,7 +220,7 @@
220220
221221// DONT_EXPORT: DynamicSymbols [
222222// DONT_EXPORT-NEXT: Symbol {
223// DONT_EXPORT-NEXT: Name: @
223// DONT_EXPORT-NEXT: Name:
224224// DONT_EXPORT-NEXT: Value: 0x0
225225// DONT_EXPORT-NEXT: Size: 0
226226// DONT_EXPORT-NEXT: Binding: Local (0x0)
......@@ -229,7 +229,7 @@
229229// DONT_EXPORT-NEXT: Section: Undefined (0x0)
230230// DONT_EXPORT-NEXT: }
231231// DONT_EXPORT-NEXT: Symbol {
232// DONT_EXPORT-NEXT: Name: bar@
232// DONT_EXPORT-NEXT: Name: bar
233233// DONT_EXPORT-NEXT: Value: 0x0
234234// DONT_EXPORT-NEXT: Size: 0
235235// DONT_EXPORT-NEXT: Binding: Global
......@@ -238,7 +238,7 @@
238238// DONT_EXPORT-NEXT: Section: Undefined
239239// DONT_EXPORT-NEXT: }
240240// DONT_EXPORT-NEXT: Symbol {
241// DONT_EXPORT-NEXT: Name: zed@
241// DONT_EXPORT-NEXT: Name: zed
242242// DONT_EXPORT-NEXT: Value: 0x0
243243// DONT_EXPORT-NEXT: Size: 0
244244// 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 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
44# RUN: ld.lld --hash-style=sysv -no-rosegment -o %t %t.o -shared
5# RUN: llvm-readelf -s %t | FileCheck %s
5# RUN: llvm-readelf -S %t | FileCheck %s
66
77# CHECK: .dynsym {{.*}} A
88# 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 @@
1818// CHECK-NEXT: }
1919// CHECK-NEXT: Symbol {
2020// CHECK-NEXT: Name: _start
21// CHECK-NEXT: Value: 0x11000
21// CHECK-NEXT: Value: 0x401000
2222// CHECK-NEXT: Size: 0
2323// CHECK-NEXT: Binding: Global
2424// CHECK-NEXT: Type: None
deps/lld/test/ELF/strip-debug.s+3-1
......@@ -1,4 +1,4 @@
1# REQUIRES: x86
1# REQUIRES: x86, zlib
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld %t -o %t2 --strip-debug
44# RUN: llvm-readobj -sections %t2 | FileCheck %s
......@@ -12,3 +12,5 @@
1212
1313.section .debug_Foo,"",@progbits
1414.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 @@
1919# RUN: --unresolved-symbols=ignore-all --no-warn-symbol-ordering --warn-symbol-ordering 2>&1 | \
2020# 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
2722# Check that a warning is emitted for imported shared symbols.
2823# RUN: echo "shared" > %t-order-shared.txt
2924# RUN: ld.lld %t1.o %t.so -o %t --symbol-ordering-file %t-order-shared.txt \
......@@ -97,7 +92,7 @@
9792# RUN: echo "_GLOBAL_OFFSET_TABLE_" >> %t-order-multi.txt
9893# RUN: echo "_start" >> %t-order-multi.txt
9994# 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,SYNTHETIC
95# RUN: 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2,SYNTHETIC
10196
10297# WARN-NOT: warning:
10398# SAMESYM: warning: {{.*}}.txt: duplicate ordered symbol: _start
......@@ -115,10 +110,12 @@
115110# ABSOLUTE: warning: {{.*}}1.o: unable to order absolute symbol: absolute
116111# WARN-NOT: warning:
117112# MISSING: warning: symbol ordering file: no such symbol: missing
113# WARN-NOT: warning:
118114# MISSING2: warning: symbol ordering file: no such symbol: missing_sym
115# WARN-NOT: warning:
119116# COMDAT: warning: {{.*}}1.o: unable to order discarded symbol: comdat
120# MULTI: warning: {{.*}}3.o: unable to order undefined symbol: multi
121# MULTI-NEXT: warning: {{.*}}2.o: unable to order absolute symbol: multi
117# WARN-NOT: warning:
118# MULTI: warning: {{.*}}2.o: unable to order absolute symbol: multi
122119# WARN-NOT: warning:
123120
124121absolute = 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:
3232
3333// DIS: Disassembly of section test:
3434// DIS-NEXT: _start:
35// DIS-NEXT: 11000: ba 08 00 00 00 movl $8, %edx
36// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
37// DIS-NEXT: 1100c: 29 d0 subl %edx, %eax
38// DIS-NEXT: 1100e: ba 04 00 00 00 movl $4, %edx
39// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
40// DIS-NEXT: 1101a: 29 d0 subl %edx, %eax
41// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
42// DIS-NEXT: 11023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
43// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
44// DIS-NEXT: 11030: 8d 81 77 00 00 00 leal 119(%ecx), %eax
35// DIS-NEXT: 401000: ba 08 00 00 00 movl $8, %edx
36// DIS-NEXT: 401005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
37// DIS-NEXT: 40100c: 29 d0 subl %edx, %eax
38// DIS-NEXT: 40100e: ba 04 00 00 00 movl $4, %edx
39// DIS-NEXT: 401013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
40// DIS-NEXT: 40101a: 29 d0 subl %edx, %eax
41// DIS-NEXT: 40101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
42// DIS-NEXT: 401023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
43// DIS-NEXT: 401029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
44// DIS-NEXT: 401030: 8d 81 77 00 00 00 leal 119(%ecx), %eax
4545
4646// RELOC: Relocations [
4747// RELOC-NEXT: ]
deps/lld/test/ELF/tls-in-archive.s+1
......@@ -1,5 +1,6 @@
11// REQUIRES: x86
22// 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
34// RUN: llvm-ar cru %t.a %t1.o
45// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
56// 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 @@
88
99// NORELOC: Relocations [
1010// NORELOC-NEXT: Section ({{.*}}) .rel.dyn {
11// NORELOC-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
12// NORELOC-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
11// NORELOC-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
12// NORELOC-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
1313// NORELOC-NEXT: }
1414// NORELOC-NEXT: ]
1515
1616// DISASM: Disassembly of section .text:
1717// DISASM-NEXT: _start:
18// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
19// DISASM-NEXT: 11006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
20// DISASM-NEXT: 1100c: 65 a1 00 00 00 00 movl %gs:0, %eax
21// DISASM-NEXT: 11012: 03 83 fc ff ff ff addl -4(%ebx), %eax
22// DISASM-NEXT: 11018: 65 a1 00 00 00 00 movl %gs:0, %eax
23// DISASM-NEXT: 1101e: 81 e8 08 00 00 00 subl $8, %eax
24// DISASM-NEXT: 11024: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 1102a: 81 e8 04 00 00 00 subl $4, %eax
18// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
19// DISASM-NEXT: 401006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
20// DISASM-NEXT: 40100c: 65 a1 00 00 00 00 movl %gs:0, %eax
21// DISASM-NEXT: 401012: 03 83 fc ff ff ff addl -4(%ebx), %eax
22// DISASM-NEXT: 401018: 65 a1 00 00 00 00 movl %gs:0, %eax
23// DISASM-NEXT: 40101e: 81 e8 08 00 00 00 subl $8, %eax
24// DISASM-NEXT: 401024: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 40102a: 81 e8 04 00 00 00 subl $4, %eax
2626
2727.type tlsexe1,@object
2828.section .tbss,"awT",@nobits
deps/lld/test/ELF/tls-opt-i686.s+16-16
......@@ -10,25 +10,25 @@
1010// DISASM: Disassembly of section .text:
1111// DISASM-NEXT: _start:
1212// LD -> LE:
13// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
14// DISASM-NEXT: 11006: 90 nop
15// DISASM-NEXT: 11007: 8d 74 26 00 leal (%esi,%eiz), %esi
16// DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
17// DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax
18// DISASM-NEXT: 11017: 90 nop
19// DISASM-NEXT: 11018: 8d 74 26 00 leal (%esi,%eiz), %esi
20// DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
13// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
14// DISASM-NEXT: 401006: 90 nop
15// DISASM-NEXT: 401007: 8d 74 26 00 leal (%esi,%eiz), %esi
16// DISASM-NEXT: 40100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
17// DISASM-NEXT: 401011: 65 a1 00 00 00 00 movl %gs:0, %eax
18// DISASM-NEXT: 401017: 90 nop
19// DISASM-NEXT: 401018: 8d 74 26 00 leal (%esi,%eiz), %esi
20// DISASM-NEXT: 40101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
2121// IE -> LE:
2222// 4294967288 == 0xFFFFFFF8
2323// 4294967292 == 0xFFFFFFFC
24// DISASM-NEXT: 11022: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 11028: c7 c0 f8 ff ff ff movl $4294967288, %eax
26// DISASM-NEXT: 1102e: 65 a1 00 00 00 00 movl %gs:0, %eax
27// DISASM-NEXT: 11034: c7 c0 fc ff ff ff movl $4294967292, %eax
28// DISASM-NEXT: 1103a: 65 a1 00 00 00 00 movl %gs:0, %eax
29// DISASM-NEXT: 11040: 8d 80 f8 ff ff ff leal -8(%eax), %eax
30// DISASM-NEXT: 11046: 65 a1 00 00 00 00 movl %gs:0, %eax
31// DISASM-NEXT: 1104c: 8d 80 fc ff ff ff leal -4(%eax), %eax
24// DISASM-NEXT: 401022: 65 a1 00 00 00 00 movl %gs:0, %eax
25// DISASM-NEXT: 401028: c7 c0 f8 ff ff ff movl $4294967288, %eax
26// DISASM-NEXT: 40102e: 65 a1 00 00 00 00 movl %gs:0, %eax
27// DISASM-NEXT: 401034: c7 c0 fc ff ff ff movl $4294967292, %eax
28// DISASM-NEXT: 40103a: 65 a1 00 00 00 00 movl %gs:0, %eax
29// DISASM-NEXT: 401040: 8d 80 f8 ff ff ff leal -8(%eax), %eax
30// DISASM-NEXT: 401046: 65 a1 00 00 00 00 movl %gs:0, %eax
31// DISASM-NEXT: 40104c: 8d 80 fc ff ff ff leal -4(%eax), %eax
3232.type tls0,@object
3333.section .tbss,"awT",@nobits
3434.globl tls0
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s+21-21
......@@ -14,7 +14,7 @@
1414// GOTREL-NEXT: SHF_ALLOC
1515// GOTREL-NEXT: SHF_WRITE
1616// GOTREL-NEXT: ]
17// GOTREL-NEXT: Address: 0x12058
17// GOTREL-NEXT: Address: 0x402058
1818// GOTREL-NEXT: Offset: 0x2058
1919// GOTREL-NEXT: Size: 8
2020// GOTREL-NEXT: Link: 0
......@@ -24,8 +24,8 @@
2424// GOTREL-NEXT: }
2525// GOTREL: Relocations [
2626// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
27// GOTREL-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
28// GOTREL-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
27// GOTREL-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
28// GOTREL-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
2929// GOTREL-NEXT: }
3030// GOTREL-NEXT: ]
3131
......@@ -33,24 +33,24 @@
3333// DISASM-NEXT: _start:
3434// 4294967288 = 0xFFFFFFF8
3535// 4294967292 = 0xFFFFFFFC
36// 73808 = (.got)[0] = 0x12058
37// 73812 = (.got)[1] = 0x1205C
38// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
39// DISASM-NEXT: 11006: 65 8b 01 movl %gs:(%ecx), %eax
40// DISASM-NEXT: 11009: b8 f8 ff ff ff movl $4294967288, %eax
41// DISASM-NEXT: 1100e: 65 8b 00 movl %gs:(%eax), %eax
42// DISASM-NEXT: 11011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
43// DISASM-NEXT: 11017: 65 8b 01 movl %gs:(%ecx), %eax
44// DISASM-NEXT: 1101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
45// DISASM-NEXT: 11020: 65 8b 01 movl %gs:(%ecx), %eax
46// DISASM-NEXT: 11023: b8 fc ff ff ff movl $4294967292, %eax
47// DISASM-NEXT: 11028: 65 8b 00 movl %gs:(%eax), %eax
48// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
49// DISASM-NEXT: 11031: 65 8b 01 movl %gs:(%ecx), %eax
50// DISASM-NEXT: 11034: 8b 0d 58 20 01 00 movl 73816, %ecx
51// DISASM-NEXT: 1103a: 65 8b 01 movl %gs:(%ecx), %eax
52// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx
53// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax
36// 4202584 = (.got)[0] = 0x402058
37// 4202588 = (.got)[1] = 0x40205C
38// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
39// DISASM-NEXT: 401006: 65 8b 01 movl %gs:(%ecx), %eax
40// DISASM-NEXT: 401009: b8 f8 ff ff ff movl $4294967288, %eax
41// DISASM-NEXT: 40100e: 65 8b 00 movl %gs:(%eax), %eax
42// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
43// DISASM-NEXT: 401017: 65 8b 01 movl %gs:(%ecx), %eax
44// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
45// DISASM-NEXT: 401020: 65 8b 01 movl %gs:(%ecx), %eax
46// DISASM-NEXT: 401023: b8 fc ff ff ff movl $4294967292, %eax
47// DISASM-NEXT: 401028: 65 8b 00 movl %gs:(%eax), %eax
48// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
49// DISASM-NEXT: 401031: 65 8b 01 movl %gs:(%ecx), %eax
50// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx
51// DISASM-NEXT: 40103a: 65 8b 01 movl %gs:(%ecx), %eax
52// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx
53// DISASM-NEXT: 401043: 65 8b 01 movl %gs:(%ecx), %eax
5454
5555.type tlslocal0,@object
5656.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 @@
44// RUN: ld.lld -static %t -o %tout
55// RUN: ld.lld %t -o %tout
66// RUN: ld.lld -shared %tso -o %tshared
7// RUN: ld.lld -static %t %tshared -o %tout
87
98.global _start
109_start:
deps/lld/test/ELF/tls-weak-undef.s+1
......@@ -4,6 +4,7 @@
44
55// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
66// RUN: %p/Inputs/tls-in-archive.s -o %t1.o
7// RUN: rm -f %t.a
78// RUN: llvm-ar cru %t.a %t1.o
89// RUN: ld.lld %t.o %t.a -o %t
910
deps/lld/test/ELF/trace-ar.s+1
......@@ -2,6 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o
44# 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
56# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o
67
78## Check how -t works with achieves
deps/lld/test/ELF/trace-symbols.s+2
......@@ -8,7 +8,9 @@
88# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2
99# RUN: ld.lld -shared %t1 -o %t1.so
1010# RUN: ld.lld -shared %t2 -o %t2.so
11# RUN: rm -f %t1.a
1112# RUN: llvm-ar rcs %t1.a %t1
13# RUN: rm -f %t2.a
1214# RUN: llvm-ar rcs %t2.a %t2
1315
1416# 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 @@
55# The debug info has a broken relocation. Check that we don't crash
66# and still report the undefined symbol.
77
8# CHECK: error: unsupported relocation target while parsing debug info
8# CHECK: error: {{.*}}.o: relocation R_X86_64_64 at 0x29 has unsupported target
99# CHECK: error: undefined symbol: bar
1010
1111--- !ELF
deps/lld/test/ELF/undef-version-script.s+3-3
......@@ -6,7 +6,7 @@
66
77# CHECK: DynamicSymbols [
88# CHECK-NEXT: Symbol {
9# CHECK-NEXT: Name: @
9# CHECK-NEXT: Name:
1010# CHECK-NEXT: Value: 0x0
1111# CHECK-NEXT: Size: 0
1212# CHECK-NEXT: Binding: Local (0x0)
......@@ -15,7 +15,7 @@
1515# CHECK-NEXT: Section: Undefined (0x0)
1616# CHECK-NEXT: }
1717# CHECK-NEXT: Symbol {
18# CHECK-NEXT: Name: bar@
18# CHECK-NEXT: Name: bar
1919# CHECK-NEXT: Value: 0x0
2020# CHECK-NEXT: Size: 0
2121# CHECK-NEXT: Binding: Weak (0x2)
......@@ -24,7 +24,7 @@
2424# CHECK-NEXT: Section: Undefined (0x0)
2525# CHECK-NEXT: }
2626# CHECK-NEXT: Symbol {
27# CHECK-NEXT: Name: foo@
27# CHECK-NEXT: Name: foo
2828# CHECK-NEXT: Value: 0x0
2929# CHECK-NEXT: Size: 0
3030# 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
1717// CHECK-NEXT: SHF_ALLOC
1818// CHECK-NEXT: SHF_EXECINSTR
1919// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x11010
20// CHECK-NEXT: Address: 0x401010
2121
2222// CHECK: Name: set_data
23// CHECK-NEXT: Value: 0x11020
23// CHECK-NEXT: Value: 0x401020
deps/lld/test/ELF/undef.s+5
......@@ -3,6 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o
55# 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
67# RUN: llvm-ar rc %t2.a %t2.o
78# RUN: not ld.lld %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s
89# RUN: not ld.lld -pie %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s
......@@ -19,6 +20,9 @@
1920# CHECK: >>> referenced by undef.s
2021# 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
2226# CHECK: error: undefined symbol: zed2
2327# CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a
2428
......@@ -59,3 +63,4 @@ _start:
5963 call bar
6064 call zed1
6165 call _Z3fooi
66 call _ZTV3Foo
deps/lld/test/ELF/verdef-defaultver.s+4-4
......@@ -8,7 +8,7 @@
88
99# DSO: DynamicSymbols [
1010# DSO-NEXT: Symbol {
11# DSO-NEXT: Name: @
11# DSO-NEXT: Name:
1212# DSO-NEXT: Value: 0x0
1313# DSO-NEXT: Size: 0
1414# DSO-NEXT: Binding: Local
......@@ -61,7 +61,7 @@
6161# DSO-NEXT: Symbols [
6262# DSO-NEXT: Symbol {
6363# DSO-NEXT: Version: 0
64# DSO-NEXT: Name: @
64# DSO-NEXT: Name:
6565# DSO-NEXT: }
6666# DSO-NEXT: Symbol {
6767# DSO-NEXT: Version: 2
......@@ -112,7 +112,7 @@
112112
113113# EXE: DynamicSymbols [
114114# EXE-NEXT: Symbol {
115# EXE-NEXT: Name: @
115# EXE-NEXT: Name:
116116# EXE-NEXT: Value: 0x0
117117# EXE-NEXT: Size: 0
118118# EXE-NEXT: Binding: Local
......@@ -156,7 +156,7 @@
156156# EXE-NEXT: Symbols [
157157# EXE-NEXT: Symbol {
158158# EXE-NEXT: Version: 0
159# EXE-NEXT: Name: @
159# EXE-NEXT: Name:
160160# EXE-NEXT: }
161161# EXE-NEXT: Symbol {
162162# EXE-NEXT: Version: 2
deps/lld/test/ELF/verdef.s+2-2
......@@ -14,7 +14,7 @@
1414# DSO-NEXT: Symbols [
1515# DSO-NEXT: Symbol {
1616# DSO-NEXT: Version: 0
17# DSO-NEXT: Name: @
17# DSO-NEXT: Name:
1818# DSO-NEXT: }
1919# DSO-NEXT: Symbol {
2020# DSO-NEXT: Version: 2
......@@ -76,7 +76,7 @@
7676# MAIN-NEXT: Symbols [
7777# MAIN-NEXT: Symbol {
7878# MAIN-NEXT: Version: 0
79# MAIN-NEXT: Name: @
79# MAIN-NEXT: Name:
8080# MAIN-NEXT: }
8181# MAIN-NEXT: Symbol {
8282# MAIN-NEXT: Version: 2
deps/lld/test/ELF/verneed.s+2-2
......@@ -76,7 +76,7 @@
7676
7777# CHECK: DynamicSymbols [
7878# CHECK-NEXT: Symbol {
79# CHECK-NEXT: Name: @
79# CHECK-NEXT: Name:
8080# CHECK-NEXT: Value: 0x0
8181# CHECK-NEXT: Size: 0
8282# CHECK-NEXT: Binding: Local (0x0)
......@@ -125,7 +125,7 @@
125125# CHECK-NEXT: Symbols [
126126# CHECK-NEXT: Symbol {
127127# CHECK-NEXT: Version: 0
128# CHECK-NEXT: Name: @
128# CHECK-NEXT: Name:
129129# CHECK-NEXT: }
130130# CHECK-NEXT: Symbol {
131131# CHECK-NEXT: Version: 2
deps/lld/test/ELF/version-exclude-libs.s+1
......@@ -1,5 +1,6 @@
11// REQUIRES: x86
22// RUN: llvm-mc %p/Inputs/versiondef.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: rm -f %t.a
34// RUN: llvm-ar -r %t.a %t.o
45// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
56// 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 @@
44# RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
66# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
7# ABC: Name: _Z3abbi@
7# ABC: Name: _Z3abbi
88# ABC: Name: _Z3abci@@FOO
99
1010# RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script
1111# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so
1212# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB
1313# ABB: Name: _Z3abbi@@FOO
14# ABB: Name: _Z3abci@
14# ABB: Name: _Z3abci
1515
1616# RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script
1717# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
......@@ -34,8 +34,8 @@
3434# RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script
3535# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so
3636# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO
37# NO: Name: _Z3abbi@
38# NO: Name: _Z3abci@
37# NO: Name: _Z3abbi
38# NO: Name: _Z3abci
3939
4040# RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script
4141# 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 @@
88# CHECK: Symbols [
99# CHECK-NEXT: Symbol {
1010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @
11# CHECK-NEXT: Name:
1212# CHECK-NEXT: }
1313# CHECK-NEXT: Symbol {
1414# CHECK-NEXT: Version: 1
15# CHECK-NEXT: Name: _Z3abbi@
15# CHECK-NEXT: Name: _Z3abbi
1616# CHECK-NEXT: }
1717# CHECK-NEXT: ]
1818
deps/lld/test/ELF/version-script-extern-wildcards.s+1-1
......@@ -8,7 +8,7 @@
88
99# CHECK: Version symbols {
1010# CHECK: Symbols [
11# CHECK: Name: _Z3bari@
11# CHECK: Name: _Z3bari
1212# CHECK: Name: _Z3fooi@@FOO
1313# CHECK: Name: _Z3zedi@@BAR
1414
deps/lld/test/ELF/version-script-extern.s+2-2
......@@ -12,7 +12,7 @@
1212
1313# DSO: DynamicSymbols [
1414# DSO-NEXT: Symbol {
15# DSO-NEXT: Name: @
15# DSO-NEXT: Name:
1616# DSO-NEXT: Value: 0x0
1717# DSO-NEXT: Size: 0
1818# DSO-NEXT: Binding: Local
......@@ -74,7 +74,7 @@
7474# DSO-NEXT: Symbols [
7575# DSO-NEXT: Symbol {
7676# DSO-NEXT: Version: 0
77# DSO-NEXT: Name: @
77# DSO-NEXT: Name:
7878# DSO-NEXT: }
7979# DSO-NEXT: Symbol {
8080# DSO-NEXT: Version: 3
deps/lld/test/ELF/version-script-extern2.s+1-1
......@@ -8,7 +8,7 @@
88# CHECK: Symbols [
99# CHECK-NEXT: Symbol {
1010# CHECK-NEXT: Version: 0
11# CHECK-NEXT: Name: @
11# CHECK-NEXT: Name:
1212# CHECK-NEXT: }
1313# CHECK-NEXT: Symbol {
1414# CHECK-NEXT: Version: 2
deps/lld/test/ELF/version-script-hide-so-symbol.s+1-1
......@@ -12,7 +12,7 @@
1212
1313# CHECK: DynamicSymbols [
1414# CHECK-NEXT: Symbol {
15# CHECK-NEXT: Name: @ (0)
15# CHECK-NEXT: Name:
1616# CHECK-NEXT: Value: 0x0
1717# CHECK-NEXT: Size: 0
1818# CHECK-NEXT: Binding: Local
deps/lld/test/ELF/version-script-locals-extern.s+4-4
......@@ -7,11 +7,11 @@
77# ABB: Symbols [
88# ABB-NEXT: Symbol {
99# ABB-NEXT: Version: 0
10# ABB-NEXT: Name: @
10# ABB-NEXT: Name:
1111# ABB-NEXT: }
1212# ABB-NEXT: Symbol {
1313# ABB-NEXT: Version: 1
14# ABB-NEXT: Name: _Z3abci@
14# ABB-NEXT: Name: _Z3abci
1515# ABB-NEXT: }
1616# ABB-NEXT: ]
1717
......@@ -26,11 +26,11 @@
2626# ABC: Symbols [
2727# ABC-NEXT: Symbol {
2828# ABC-NEXT: Version: 0
29# ABC-NEXT: Name: @
29# ABC-NEXT: Name:
3030# ABC-NEXT: }
3131# ABC-NEXT: Symbol {
3232# ABC-NEXT: Version: 1
33# ABC-NEXT: Name: _Z3abbi@
33# ABC-NEXT: Name: _Z3abbi
3434# ABC-NEXT: }
3535# ABC-NEXT: ]
3636
deps/lld/test/ELF/version-script-symver2.s+1-1
......@@ -7,7 +7,7 @@
77# CHECK: Symbols [
88# CHECK-NEXT: Symbol {
99# CHECK-NEXT: Version: 0
10# CHECK-NEXT: Name: @
10# CHECK-NEXT: Name:
1111# CHECK-NEXT: }
1212# CHECK-NEXT: Symbol {
1313# CHECK-NEXT: Version: 3
deps/lld/test/ELF/version-script-weak.s+1-1
......@@ -14,7 +14,7 @@
1414# CHECK-NEXT: }
1515# CHECK-NEXT: ]
1616# CHECK: Symbol {
17# CHECK: Name: foo@
17# CHECK: Name: foo
1818# CHECK-NEXT: Value: 0x0
1919# CHECK-NEXT: Size: 0
2020# CHECK-NEXT: Binding: Weak
deps/lld/test/ELF/version-script.s+14-14
......@@ -50,7 +50,7 @@
5050
5151# DSO: DynamicSymbols [
5252# DSO-NEXT: Symbol {
53# DSO-NEXT: Name: @
53# DSO-NEXT: Name:
5454# DSO-NEXT: Value: 0x0
5555# DSO-NEXT: Size: 0
5656# DSO-NEXT: Binding: Local (0x0)
......@@ -59,7 +59,7 @@
5959# DSO-NEXT: Section: Undefined (0x0)
6060# DSO-NEXT: }
6161# DSO-NEXT: Symbol {
62# DSO-NEXT: Name: bar@
62# DSO-NEXT: Name: bar
6363# DSO-NEXT: Value: 0x0
6464# DSO-NEXT: Size: 0
6565# DSO-NEXT: Binding: Global (0x1)
......@@ -68,7 +68,7 @@
6868# DSO-NEXT: Section: Undefined (0x0)
6969# DSO-NEXT: }
7070# DSO-NEXT: Symbol {
71# DSO-NEXT: Name: foo1@
71# DSO-NEXT: Name: foo1
7272# DSO-NEXT: Value: 0x1000
7373# DSO-NEXT: Size: 0
7474# DSO-NEXT: Binding: Global (0x1)
......@@ -77,7 +77,7 @@
7777# DSO-NEXT: Section: .text
7878# DSO-NEXT: }
7979# DSO-NEXT: Symbol {
80# DSO-NEXT: Name: foo3@
80# DSO-NEXT: Name: foo3
8181# DSO-NEXT: Value: 0x1007
8282# DSO-NEXT: Size: 0
8383# DSO-NEXT: Binding: Global (0x1)
......@@ -89,7 +89,7 @@
8989
9090# DSO2: DynamicSymbols [
9191# DSO2-NEXT: Symbol {
92# DSO2-NEXT: Name: @
92# DSO2-NEXT: Name:
9393# DSO2-NEXT: Value: 0x0
9494# DSO2-NEXT: Size: 0
9595# DSO2-NEXT: Binding: Local (0x0)
......@@ -98,7 +98,7 @@
9898# DSO2-NEXT: Section: Undefined (0x0)
9999# DSO2-NEXT: }
100100# DSO2-NEXT: Symbol {
101# DSO2-NEXT: Name: bar@
101# DSO2-NEXT: Name: bar
102102# DSO2-NEXT: Value: 0x0
103103# DSO2-NEXT: Size: 0
104104# DSO2-NEXT: Binding: Global (0x1)
......@@ -110,7 +110,7 @@
110110
111111# VERDSO: DynamicSymbols [
112112# VERDSO-NEXT: Symbol {
113# VERDSO-NEXT: Name: @
113# VERDSO-NEXT: Name:
114114# VERDSO-NEXT: Value: 0x0
115115# VERDSO-NEXT: Size: 0
116116# VERDSO-NEXT: Binding: Local
......@@ -119,7 +119,7 @@
119119# VERDSO-NEXT: Section: Undefined
120120# VERDSO-NEXT: }
121121# VERDSO-NEXT: Symbol {
122# VERDSO-NEXT: Name: bar@
122# VERDSO-NEXT: Name: bar
123123# VERDSO-NEXT: Value: 0x0
124124# VERDSO-NEXT: Size: 0
125125# VERDSO-NEXT: Binding: Global
......@@ -158,7 +158,7 @@
158158
159159# ALL: DynamicSymbols [
160160# ALL-NEXT: Symbol {
161# ALL-NEXT: Name: @
161# ALL-NEXT: Name:
162162# ALL-NEXT: Value: 0x0
163163# ALL-NEXT: Size: 0
164164# ALL-NEXT: Binding: Local
......@@ -167,7 +167,7 @@
167167# ALL-NEXT: Section: Undefined
168168# ALL-NEXT: }
169169# ALL-NEXT: Symbol {
170# ALL-NEXT: Name: _start@
170# ALL-NEXT: Name: _start
171171# ALL-NEXT: Value:
172172# ALL-NEXT: Size: 0
173173# ALL-NEXT: Binding: Global
......@@ -176,7 +176,7 @@
176176# ALL-NEXT: Section: .text
177177# ALL-NEXT: }
178178# ALL-NEXT: Symbol {
179# ALL-NEXT: Name: bar@
179# ALL-NEXT: Name: bar
180180# ALL-NEXT: Value:
181181# ALL-NEXT: Size: 0
182182# ALL-NEXT: Binding: Global
......@@ -185,7 +185,7 @@
185185# ALL-NEXT: Section: Undefined
186186# ALL-NEXT: }
187187# ALL-NEXT: Symbol {
188# ALL-NEXT: Name: foo1@
188# ALL-NEXT: Name: foo1
189189# ALL-NEXT: Value:
190190# ALL-NEXT: Size: 0
191191# ALL-NEXT: Binding: Global
......@@ -194,7 +194,7 @@
194194# ALL-NEXT: Section: .text
195195# ALL-NEXT: }
196196# ALL-NEXT: Symbol {
197# ALL-NEXT: Name: foo2@
197# ALL-NEXT: Name: foo2
198198# ALL-NEXT: Value:
199199# ALL-NEXT: Size: 0
200200# ALL-NEXT: Binding: Global
......@@ -203,7 +203,7 @@
203203# ALL-NEXT: Section: .text
204204# ALL-NEXT: }
205205# ALL-NEXT: Symbol {
206# ALL-NEXT: Name: foo3@
206# ALL-NEXT: Name: foo3
207207# ALL-NEXT: Value:
208208# ALL-NEXT: Size: 0
209209# ALL-NEXT: Binding: Global
deps/lld/test/ELF/version-wildcard.test+2-2
......@@ -7,7 +7,7 @@
77
88# CHECK: DynamicSymbols [
99# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Name: @
10# CHECK-NEXT: Name:
1111# CHECK-NEXT: Value: 0x0
1212# CHECK-NEXT: Size: 0
1313# CHECK-NEXT: Binding: Local
......@@ -52,7 +52,7 @@
5252
5353# MIX: DynamicSymbols [
5454# MIX-NEXT: Symbol {
55# MIX-NEXT: Name: @
55# MIX-NEXT: Name:
5656# MIX-NEXT: Value: 0x0
5757# MIX-NEXT: Size: 0
5858# MIX-NEXT: Binding: Local
deps/lld/test/ELF/visibility.s+1-1
......@@ -82,7 +82,7 @@
8282
8383// CHECK: DynamicSymbols [
8484// CHECK-NEXT: Symbol {
85// CHECK-NEXT: Name: @
85// CHECK-NEXT: Name:
8686// CHECK-NEXT: Value: 0x0
8787// CHECK-NEXT: Size: 0
8888// CHECK-NEXT: Binding: Local
deps/lld/test/ELF/weak-undef-export.s+2-2
......@@ -8,7 +8,7 @@
88
99# CHECK: DynamicSymbols [
1010# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name: @ (0)
11# CHECK-NEXT: Name:
1212# CHECK-NEXT: Value: 0x0
1313# CHECK-NEXT: Size: 0
1414# CHECK-NEXT: Binding: Local (0x0)
......@@ -17,7 +17,7 @@
1717# CHECK-NEXT: Section: Undefined (0x0)
1818# CHECK-NEXT: }
1919# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: foo@ (1)
20# CHECK-NEXT: Name: foo
2121# CHECK-NEXT: Value: 0x0
2222# CHECK-NEXT: Size: 0
2323# CHECK-NEXT: Binding: Weak (0x2)
deps/lld/test/ELF/weak-undef.s+2-2
......@@ -5,7 +5,7 @@
55
66# CHECK: DynamicSymbols [
77# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @
8# CHECK-NEXT: Name:
99# CHECK-NEXT: Value: 0x0
1010# CHECK-NEXT: Size: 0
1111# CHECK-NEXT: Binding: Local (0x0)
......@@ -14,7 +14,7 @@
1414# CHECK-NEXT: Section: Undefined (0x0)
1515# CHECK-NEXT: }
1616# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: foo@
17# CHECK-NEXT: Name: foo
1818# CHECK-NEXT: Value: 0x0
1919# CHECK-NEXT: Size: 0
2020# 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 @@
1515// CHECK-NEXT: movl $0x11010, %edx
1616// CHECK-NEXT: movl $0x11000, %edx
1717
18// RUN: llvm-readobj -t %t | FileCheck -check-prefix=SYM %s
18// 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 [
24// SYM-NEXT: Symbol {
25// SYM-NEXT: Name: (0)
26// SYM-NEXT: Value:
27// SYM-NEXT: Size:
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: ]
21// SYM: 0000000000202000 .dynamic 00000000 .hidden _DYNAMIC
22// SYM-NEXT: 0000000000011000 *ABS* 00000000 __real_foo
23// SYM-NEXT: 0000000000011010 *ABS* 00000000 __wrap_foo
24// SYM-NEXT: 0000000000201000 .text 00000000 _start
25// SYM-NEXT: 0000000000011000 *ABS* 00000000 foo
7226
7327.global _start
7428_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 @@
3434// SYM2-NEXT: STV_PROTECTED
3535// SYM2-NEXT: ]
3636// SYM3: Name: __real_foo
37// SYM3-NEXT: Value: 0x11020
37// SYM3-NEXT: Value: 0x11000
3838// SYM3-NEXT: Size:
3939// SYM3-NEXT: Binding: Global
4040// 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 @@
44
55## Check we are able to find a function symbol that encloses
66## 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
99# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
1010.section .rodata.str1,"aMS",@progbits,1
deps/lld/test/ELF/x86-64-reloc-gotoff64.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -shared -o %t.so
4// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION
4// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
55// RUN: llvm-objdump -d %t.so | FileCheck %s
66
77// SECTION: .dynamic DYNAMIC 0000000000003000
deps/lld/test/ELF/x86-64-reloc-gotpc64.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -shared -o %t.so
4// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION
4// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
55// RUN: llvm-objdump -d %t.so | FileCheck %s
66
77// SECTION: .got PROGBITS 0000000000003070 003070 000000
deps/lld/test/ELF/x86-64-reloc-range-debug-loc.s+1-1
......@@ -5,7 +5,7 @@
55
66## Check we are able to report file and location from debug information
77## 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
1010.section .text,"ax",@progbits
1111foo:
deps/lld/test/ELF/x86-64-reloc-range.s+2
......@@ -1,6 +1,8 @@
11// REQUIRES: x86
22// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
33// 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
57// CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647]
68// 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 @@
11# REQUIRES: x86
22# 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.o
3# 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 %s
6# 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
78# An unknown prologue gives a match failure
8# CHECK: unable to adjust the enclosing function's
9# CHECK: error: {{.*}}.o:(.text): unknown_prologue (with -fsplit-stack) calls non_split (without -fsplit-stack), but couldn't adjust its prologue
910
1011# 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 link
12# 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
1317 .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 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
33# 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 %t
5# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o -o %t
66# RUN: llvm-objdump -d %t 2>&1 | FileCheck %s
77
88# 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 @@
11# REQUIRES: x86
22# 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.o
3# 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 notext
6# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o %t3.o -o %t -z notext
67# RUN: llvm-objdump -d %t | FileCheck %s
78
89# Avoid duplicating the prologue for every test via macros.
......@@ -25,11 +26,11 @@ prologue1_calls_\function_to_call:
2526 .size prologue1_calls_\function_to_call,. - prologue1_calls_\function_to_call
2627.endm
2728
28.macro prologue2 function_to_call register
29.macro prologue2 function_to_call register compare_amount
2930 .global prologue2_calls_\function_to_call\register
3031 .type prologue2_calls_\function_to_call\register,@function
3132prologue2_calls_\function_to_call\register:
32 lea -0x200(%rsp),%\register
33 lea -\compare_amount(%rsp),%\register
3334 cmp %fs:0x70,%\register
3435 jae 1f
3536 callq __morestack
......@@ -65,20 +66,20 @@ prologue1 split
6566# calls plain __morestack, that any raw bytes written to the prologue
6667# make sense, and that the register number is preserved.
6768# CHECK: prologue2_calls_splitr10:
68# CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r10
69# CHECK-NEXT: lea{{.*}} -512(%rsp),{{.*}}%r10
6970# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}
7071# CHECK: jae{{.*}}
7172# CHECK-NEXT: callq{{.*}}<__morestack>
7273
73prologue2 split r10
74prologue2 split r10 0x200
7475
7576# CHECK: prologue2_calls_splitr11:
76# CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r11
77# CHECK-NEXT: lea{{.*}} -256(%rsp),{{.*}}%r11
7778# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}}
7879# CHECK: jae{{.*}}
7980# CHECK-NEXT: callq{{.*}}<__morestack>
8081
81prologue2 split r11
82prologue2 split r11 0x100
8283
8384# For split-stack code calling non-split-stack code, ensure prologue v1
8485# calls __morestack_non_split, and that any raw bytes written to the prologue
......@@ -95,30 +96,20 @@ prologue1 non_split
9596# calls __morestack_non_split, that any raw bytes written to the prologue
9697# make sense, and that the register number is preserved
9798# CHECK: prologue2_calls_non_splitr10:
98# CHECK-NEXT: lea{{.*$}}
99# CHECK-NEXT: lea{{.*}} -16640(%rsp),{{.*}}%r10
99100# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r10
100101# CHECK: jae{{.*$}}
101102# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
102103
103prologue2 non_split r10
104prologue2 non_split r10 0x100
104105
105106# CHECK: prologue2_calls_non_splitr11:
106# CHECK-NEXT: lea{{.*$}}
107# CHECK-NEXT: lea{{.*}} -16896(%rsp),{{.*}}%r11
107108# CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r11
108109# CHECK: jae{{.*$}}
109110# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
110111
111prologue2 non_split r11
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
112prologue2 non_split r11 0x200
122113
123114 .section .note.GNU-stack,"",@progbits
124115 .section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/znotext-plt-relocations-protected.s+6-1
......@@ -4,7 +4,12 @@
44# RUN: ld.lld %t2.o -o %t2.so -shared
55# RUN: not ld.lld -z notext %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s
66
7# CHECK: error: cannot preempt symbol: foo
7# 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
914.global _start
1015_start:
deps/lld/test/ELF/zstack-size.s+3
......@@ -6,6 +6,9 @@
66# RUN: ld.lld -z stack-size=0 %t -o %t2
77# 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
912.global _start
1013_start:
1114 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
145145RUN: ld.lld -### foo.o -m i386pep -Map=bar.map | FileCheck -check-prefix=MAP %s
146146RUN: ld.lld -### foo.o -m i386pep --Map=bar.map | FileCheck -check-prefix=MAP %s
147147MAP: -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 = [
4545
4646llvm_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
4853# When running under valgrind, we mangle '-vg' onto the end of the triple so we
4954# can check it with XFAIL and XTARGET.
5055if lit_config.useValgrind:
5156 config.target_triple += '-vg'
5257
5358# Running on ELF based *nix
54if platform.system() in ['FreeBSD', 'Linux']:
59if platform.system() in ['FreeBSD', 'NetBSD', 'Linux']:
5560 config.available_features.add('system-linker-elf')
5661
5762# Set if host-cxxabi's demangler can handle target's symbols.
......@@ -67,7 +72,9 @@ llvm_config.feature_config(
6772 'AVR': 'avr',
6873 'Hexagon': 'hexagon',
6974 'Mips': 'mips',
75 'MSP430': 'msp430',
7076 'PowerPC': 'ppc',
77 'RISCV': 'riscv',
7178 'Sparc': 'sparc',
7279 'WebAssembly': 'wasm',
7380 'X86': 'x86'})
......@@ -93,7 +100,10 @@ if config.have_dia_sdk:
93100tar_executable = lit.util.which('tar', config.environment['PATH'])
94101if tar_executable:
95102 tar_version = subprocess.Popen(
96 [tar_executable, '--version'], stdout=subprocess.PIPE, env={'LANG': 'C'})
97 if 'GNU tar' in tar_version.stdout.read().decode():
103 [tar_executable, '--version'],
104 stdout=subprocess.PIPE,
105 stderr=subprocess.PIPE,
106 env={'LANG': 'C'})
107 sout, _ = tar_version.communicate()
108 if 'GNU tar' in sout.decode():
98109 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:
2525 key, = e.args
2626 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
3031# Let the main config do the real work.
3132lit_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:
3636# CHECK: content: [ 61, 62, 63, 00 ]
3737# CHECK: merge: by-content
3838# CHECK: section-choice: custom-required
39# CHECK: section-name: __TEXT/__objc_methname
39# CHECK: section-name: '__TEXT/__objc_methname'
4040# CHECK: - scope: hidden
4141# CHECK: type: c-string
4242# CHECK: content: [ 64, 65, 66, 00 ]
4343# CHECK: merge: by-content
4444# CHECK: section-choice: custom-required
45# CHECK: section-name: __TEXT/__objc_methname
45# CHECK: section-name: '__TEXT/__objc_methname'
4646# CHECK: - scope: hidden
4747# CHECK: type: c-string
4848# CHECK: content: [ 61, 62, 63, 00 ]
4949# CHECK: merge: by-content
5050# CHECK: section-choice: custom-required
51# CHECK: section-name: __TEXT/__objc_classname
51# CHECK: section-name: '__TEXT/__objc_classname'
5252# CHECK: - scope: hidden
5353# CHECK: type: c-string
5454# CHECK: content: [ 67, 68, 69, 00 ]
5555# CHECK: merge: by-content
5656# CHECK: section-choice: custom-required
57# CHECK: section-name: __TEXT/__objc_classname
57# CHECK: section-name: '__TEXT/__objc_classname'
5858# CHECK: - scope: hidden
5959# CHECK: type: c-string
6060# 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
367367# CHECK: type: unknown
368368# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
369369# CHECK: section-choice: custom-required
370# CHECK: section-name: __DATA/__custom
370# CHECK: section-name: '__DATA/__custom'
371371# CHECK: dead-strip: never
372372
deps/lld/test/mach-o/parse-data.yaml+1-1
......@@ -115,5 +115,5 @@ global-symbols:
115115# CHECK: type: unknown
116116# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
117117# CHECK: section-choice: custom-required
118# CHECK: section-name: __CUST/__custom
118# CHECK: section-name: '__CUST/__custom'
119119
deps/lld/test/mach-o/sectcreate.yaml+1-1
......@@ -8,5 +8,5 @@
88# CHECK: type: sectcreate
99# CHECK: content: [ 68, 65, 6C, 6C, 6F, 0A ]
1010# CHECK: section-choice: custom-required
11# CHECK: section-name: __DATA/__data
11# CHECK: section-name: '__DATA/__data'
1212# 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:
3434 Offset: 0x00000004
3535 - Type: CUSTOM
3636 Name: linking
37 Version: 1
37 Version: 2
3838 SymbolTable:
3939 - Index: 0
4040 Kind: GLOBAL
deps/lld/test/wasm/Inputs/undefined-globals.yaml+1-1
......@@ -32,7 +32,7 @@ Sections:
3232 Offset: 0x00000004
3333 - Type: CUSTOM
3434 Name: linking
35 Version: 1
35 Version: 2
3636 SymbolTable:
3737 - Index: 0
3838 Kind: GLOBAL
deps/lld/test/wasm/alias.ll+2-2
......@@ -1,5 +1,5 @@
11; RUN: llc -filetype=obj -o %t.o %s
2; RUN: wasm-ld %t.o -o %t.wasm
2; RUN: wasm-ld --export=start_alias %t.o -o %t.wasm
33; RUN: obj2yaml %t.wasm | FileCheck %s
44
55target triple = "wasm32-unknown-unknown"
......@@ -25,7 +25,7 @@ entry:
2525; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
2626; CHECK-NEXT: - Type: TABLE
2727; CHECK-NEXT: Tables:
28; CHECK-NEXT: - ElemType: ANYFUNC
28; CHECK-NEXT: - ElemType: FUNCREF
2929; CHECK-NEXT: Limits:
3030; CHECK-NEXT: Flags: [ HAS_MAX ]
3131; 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 @@
33; RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o
44; RUN: llc -filetype=obj %S/Inputs/archive3.ll -o %t.a3.o
55; RUN: llc -filetype=obj %S/Inputs/hello.ll -o %t.hello.o
6; RUN: rm -f %t.a
67; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o %t.hello.o
78; RUN: rm -f %t.imports
89; 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 @@
11; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
22; RUN: llc -filetype=obj %s -o %t.o
3; RUN: wasm-ld -o %t.wasm %t2.o %t.o
3; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
66; bitcode generated from the following C code:
......@@ -60,7 +60,7 @@ define void @call_ptr(i64 (i64)* %arg) {
6060; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ]
6161; CHECK-NEXT: - Type: TABLE
6262; CHECK-NEXT: Tables:
63; CHECK-NEXT: - ElemType: ANYFUNC
63; CHECK-NEXT: - ElemType: FUNCREF
6464; CHECK-NEXT: Limits:
6565; CHECK-NEXT: Flags: [ HAS_MAX ]
6666; CHECK-NEXT: Initial: 0x00000003
......@@ -105,9 +105,6 @@ define void @call_ptr(i64 (i64)* %arg) {
105105; CHECK-NEXT: - Name: __data_end
106106; CHECK-NEXT: Kind: GLOBAL
107107; CHECK-NEXT: Index: 2
108; CHECK-NEXT: - Name: _start
109; CHECK-NEXT: Kind: FUNCTION
110; CHECK-NEXT: Index: 4
111108; CHECK-NEXT: - Name: bar
112109; CHECK-NEXT: Kind: FUNCTION
113110; CHECK-NEXT: Index: 1
......@@ -117,6 +114,9 @@ define void @call_ptr(i64 (i64)* %arg) {
117114; CHECK-NEXT: - Name: foo
118115; CHECK-NEXT: Kind: FUNCTION
119116; CHECK-NEXT: Index: 3
117; CHECK-NEXT: - Name: _start
118; CHECK-NEXT: Kind: FUNCTION
119; CHECK-NEXT: Index: 4
120120; CHECK-NEXT: - Name: indirect_func
121121; CHECK-NEXT: Kind: GLOBAL
122122; CHECK-NEXT: Index: 3
deps/lld/test/wasm/comdats.ll+1-1
......@@ -1,7 +1,7 @@
11; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o
22; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o
33; 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.o
4; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
55; RUN: obj2yaml %t.wasm | FileCheck %s
66
77target triple = "wasm32-unknown-unknown"
deps/lld/test/wasm/compress-relocs.ll+7-3
......@@ -1,9 +1,11 @@
11; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
22; RUN: llc -filetype=obj %s -o %t.o
3; RUN: wasm-ld -o %t.wasm %t2.o %t.o
3; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
44; RUN: obj2yaml %t.wasm | FileCheck %s
5
6; RUN: wasm-ld -O2 -o %t-compressed.wasm %t2.o %t.o
5; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
6; 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
79; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
810
911target triple = "wasm32-unknown-unknown-wasm"
......@@ -18,5 +20,7 @@ entry:
1820 ret void
1921}
2022
23; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
24
2125; CHECK: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
2226; COMPRESS: Body: 41002802840821004100280280081100001A20001101001A0B
deps/lld/test/wasm/cxx-mangling.ll+11-9
......@@ -1,8 +1,8 @@
11; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld --demangle -o %t_demangle.wasm %t.o
3; RUN: obj2yaml %t_demangle.wasm | FileCheck %s
4; RUN: wasm-ld --no-demangle -o %t_nodemangle.wasm %t.o
5; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s
2; RUN: wasm-ld --export=_Z3fooi --demangle -o %t_demangle.wasm %t.o
3; RUN: obj2yaml %t_demangle.wasm | FileCheck --check-prefixes=CHECK,DEMANGLE %s
4; RUN: wasm-ld --export=_Z3fooi --no-demangle -o %t_nodemangle.wasm %t.o
5; RUN: obj2yaml %t_nodemangle.wasm | FileCheck --check-prefixes=CHECK,MANGLE %s
66
77target triple = "wasm32-unknown-unknown"
88
......@@ -32,12 +32,12 @@ define void @_start() {
3232; CHECK-NEXT: - Name: __data_end
3333; CHECK-NEXT: Kind: GLOBAL
3434; CHECK-NEXT: Index: 2
35; CHECK-NEXT: - Name: _start
36; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 3
3835; CHECK-NEXT: - Name: _Z3fooi
3936; CHECK-NEXT: Kind: FUNCTION
4037; CHECK-NEXT: Index: 2
38; CHECK-NEXT: - Name: _start
39; CHECK-NEXT: Kind: FUNCTION
40; CHECK-NEXT: Index: 3
4141; CHECK-NEXT: - Type: CODE
4242; CHECK-NEXT: Functions:
4343; CHECK-NEXT: - Index: 0
......@@ -58,9 +58,11 @@ define void @_start() {
5858; CHECK-NEXT: - Index: 0
5959; CHECK-NEXT: Name: __wasm_call_ctors
6060; 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
6263; CHECK-NEXT: - Index: 2
63; CHECK-NEXT: Name: 'foo(int)'
64; DEMANGLE-NEXT: Name: 'foo(int)'
65; MANGLE-NEXT: Name: _Z3fooi
6466; CHECK-NEXT: - Index: 3
6567; CHECK-NEXT: Name: _start
6668; CHECK-NEXT: ...
deps/lld/test/wasm/data-layout.ll+10
......@@ -68,6 +68,16 @@ target triple = "wasm32-unknown-unknown"
6868; CHECK-MAX-NEXT: Initial: 0x00000002
6969; 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
7282; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o
7383; 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"
55@c = hidden global [9 x i8] c"whatever\00", align 1
66@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
811; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o
912
1013; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o
1114; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE
12; MERGE: - Type: DATA
13; MERGE-NEXT: Segments:
14; MERGE-NEXT: - SectionOffset: 7
15; MERGE-NEXT: MemoryIndex: 0
16; MERGE-NEXT: Offset:
17; MERGE-NEXT: Opcode: I32_CONST
18; MERGE-NEXT: Value: 1024
19; MERGE-NEXT: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
15; MERGE: - Type: DATA
16; MERGE: Segments:
17; MERGE: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
18; MERGE: Content: 636F6E7374616E74000000002B
19; MERGE-NOT: Content:
2020
2121; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o
2222; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE
23; SEPARATE: - Type: DATA
24; SEPARATE-NEXT: Segments:
25; SEPARATE-NEXT: - SectionOffset: 7
26; SEPARATE-NEXT: MemoryIndex: 0
27; SEPARATE-NEXT: Offset:
28; SEPARATE-NEXT: Opcode: I32_CONST
29; SEPARATE-NEXT: Value: 1024
30; SEPARATE-NEXT: Content: 68656C6C6F00
31; SEPARATE-NEXT: - SectionOffset: 19
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
23; SEPARATE: - Type: DATA
24; SEPARATE: Segments:
25; SEPARATE: Content: 68656C6C6F00
26; SEPARATE: Content: 676F6F6462796500
27; SEPARATE: Content: '776861746576657200'
28; SEPARATE: Content: 2A000000
29; SEPARATE: Content: 636F6E7374616E7400
30; SEPARATE: Content: 2B
31; SEPARATE-NOT: Content:
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")
4343
4444CHECK: DW_TAG_variable
4545CHECK-NEXT: DW_AT_name ("y")
46CHECK-NEXT: DW_AT_type (0x00000097 "int[]")
46CHECK-NEXT: DW_AT_type (0x00000097 "int[2]")
4747CHECK-NEXT: DW_AT_external (true)
4848CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")
4949CHECK-NEXT: DW_AT_decl_line (1)
......@@ -65,7 +65,7 @@ CHECK-NEXT: DW_AT_encoding (DW_ATE_unsigned)
6565
6666CHECK: DW_TAG_variable
6767CHECK-NEXT: DW_AT_name ("z")
68CHECK-NEXT: DW_AT_type (0x00000097 "int[]")
68CHECK-NEXT: DW_AT_type (0x00000097 "int[2]")
6969CHECK-NEXT: DW_AT_external (true)
7070CHECK-NEXT: DW_AT_decl_file ("{{.*}}hi_foo.c")
7171CHECK-NEXT: DW_AT_decl_line (8)
deps/lld/test/wasm/demangle.ll+8-6
......@@ -1,17 +1,19 @@
11; RUN: llc -filetype=obj %s -o %t.o
2; RUN: not wasm-ld --undefined _Z3fooi \
3; RUN: -o %t.wasm %t.o 2>&1 | FileCheck %s
2; RUN: not wasm-ld -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 \
8; RUN: -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s
6; RUN: not wasm-ld --no-demangle \
7; RUN: -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s
98
10; CHECK-NODEMANGLE: error: undefined symbol: _Z3fooi
9; CHECK-NODEMANGLE: error: {{.*}}.o: undefined symbol: _Z3fooi
1110
1211target triple = "wasm32-unknown-unknown"
1312
13declare void @_Z3fooi(i32);
14
1415define hidden void @_start() local_unnamed_addr {
1516entry:
17 call void @_Z3fooi(i32 1)
1618 ret void
1719}
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:
4242; CHECK-NOT: - Name: internal_func
4343
4444; EXPORT: - Type: EXPORT
45; EXPORT: - Name: _start
4645; EXPORT: - Name: bar
4746; EXPORT: - Name: foo
47; EXPORT: - Name: _start
4848; EXPORT-NOT: - Name: internal_func
deps/lld/test/wasm/export-table.test+1-1
......@@ -6,7 +6,7 @@
66
77# CHECK: - Type: TABLE
88# CHECK-NEXT: Tables:
9# CHECK-NEXT: - ElemType: ANYFUNC
9# CHECK-NEXT: - ElemType: FUNCREF
1010# CHECK-NEXT: Limits:
1111# CHECK-NEXT: Flags: [ HAS_MAX ]
1212# CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/export.ll+3-3
......@@ -28,10 +28,10 @@ entry:
2828; CHECK-NEXT: - Name: __data_end
2929; CHECK-NEXT: Kind: GLOBAL
3030; CHECK-NEXT: Index: 2
31; CHECK-NEXT: - Name: _start
32; CHECK-NEXT: Kind: FUNCTION
33; CHECK-NEXT: Index: 2
3431; CHECK-NEXT: - Name: hidden_function
3532; CHECK-NEXT: Kind: FUNCTION
3633; CHECK-NEXT: Index: 1
34; CHECK-NEXT: - Name: _start
35; CHECK-NEXT: Kind: FUNCTION
36; CHECK-NEXT: Index: 2
3737; CHECK-NEXT: - Type: CODE
deps/lld/test/wasm/import-memory.test+17
......@@ -31,3 +31,20 @@
3131# CHECK-MAX-NEXT: Initial: 0x00000004
3232# CHECK-MAX-NEXT: Maximum: 0x00000005
3333# 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 @@
1010# CHECK-NEXT: Field: __indirect_function_table
1111# CHECK-NEXT: Kind: TABLE
1212# CHECK-NEXT: Table:
13# CHECK-NEXT: ElemType: ANYFUNC
13# CHECK-NEXT: ElemType: FUNCREF
1414# CHECK-NEXT: Limits:
15# CHECK-NEXT: Flags: [ HAS_MAX ]
1615# CHECK-NEXT: Initial: 0x00000001
17# CHECK-NEXT: Maximum: 0x00000001
1816
deps/lld/test/wasm/load-undefined.test+6-8
......@@ -4,6 +4,7 @@
44; RUN: llc -filetype=obj %S/Inputs/ret64.ll -o %t.o
55; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t2.o
66; RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.start.o
7; RUN: rm -f %t2.a
78; RUN: llvm-ar rcs %t2.a %t2.o
89; RUN: wasm-ld %t.start.o --no-gc-sections %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64
910; RUN: obj2yaml %t.wasm | FileCheck %s
......@@ -17,9 +18,9 @@
1718; CHECK-NEXT: - Index: 1
1819; CHECK-NEXT: Name: _start
1920; CHECK-NEXT: - Index: 2
20; CHECK-NEXT: Name: ret32
21; CHECK-NEXT: - Index: 3
2221; CHECK-NEXT: Name: ret64
22; CHECK-NEXT: - Index: 3
23; CHECK-NEXT: Name: ret32
2324; CHECK-NEXT: ...
2425
2526; NO-LOAD: Name: name
......@@ -32,9 +33,6 @@
3233; NO-LOAD-NEXT: Name: ret64
3334; NO-LOAD-NEXT: ...
3435
35; Verify that referencing a symbol that doesn't exist won't work
36; RUN: not wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s
37; CHECK-UNDEFINED1: error: undefined symbol: 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
36; Verify that referencing a symbol that is not found doesn't result in a link
37; failure. This matches the behaviour of the ELF linker.
38; RUN: wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist
deps/lld/test/wasm/local-symbols.ll+3-2
......@@ -1,5 +1,6 @@
1; Test that internal symbols can still be GC'd when with --export-dynamic.
12; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld -o %t.wasm %t.o
3; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o
34; RUN: obj2yaml %t.wasm | FileCheck %s
45
56target triple = "wasm32-unknown-unknown"
......@@ -35,7 +36,7 @@ entry:
3536; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]
3637; CHECK-NEXT: - Type: TABLE
3738; CHECK-NEXT: Tables:
38; CHECK-NEXT: - ElemType: ANYFUNC
39; CHECK-NEXT: - ElemType: FUNCREF
3940; CHECK-NEXT: Limits:
4041; CHECK-NEXT: Flags: [ HAS_MAX ]
4142; CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/locals-duplicate.test+7-7
......@@ -1,6 +1,6 @@
11; RUN: llc -filetype=obj %p/Inputs/locals-duplicate1.ll -o %t1.o
22; RUN: llc -filetype=obj %p/Inputs/locals-duplicate2.ll -o %t2.o
3; RUN: wasm-ld --no-entry -o %t.wasm %t1.o %t2.o
3; RUN: wasm-ld --export-dynamic --no-entry -o %t.wasm %t1.o %t2.o
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
66; CHECK: --- !WASM
......@@ -20,7 +20,7 @@
2020; CHECK-NEXT: 1, 1, 1 ]
2121; CHECK-NEXT: - Type: TABLE
2222; CHECK-NEXT: Tables:
23; CHECK-NEXT: - ElemType: ANYFUNC
23; CHECK-NEXT: - ElemType: FUNCREF
2424; CHECK-NEXT: Limits:
2525; CHECK-NEXT: Flags: [ HAS_MAX ]
2626; CHECK-NEXT: Initial: 0x00000007
......@@ -253,7 +253,7 @@
253253; RELOC-NEXT: 0, 0 ]
254254; RELOC-NEXT: - Type: TABLE
255255; RELOC-NEXT: Tables:
256; RELOC-NEXT: - ElemType: ANYFUNC
256; RELOC-NEXT: - ElemType: FUNCREF
257257; RELOC-NEXT: Limits:
258258; RELOC-NEXT: Flags: [ HAS_MAX ]
259259; RELOC-NEXT: Initial: 0x00000007
......@@ -382,7 +382,7 @@
382382; RELOC-NEXT: Content: '0000000000000000'
383383; RELOC-NEXT: - Type: CUSTOM
384384; RELOC-NEXT: Name: linking
385; RELOC-NEXT: Version: 1
385; RELOC-NEXT: Version: 2
386386; RELOC-NEXT: SymbolTable:
387387; RELOC-NEXT: - Index: 0
388388; RELOC-NEXT: Kind: FUNCTION
......@@ -516,15 +516,15 @@
516516; RELOC-NEXT: SegmentInfo:
517517; RELOC-NEXT: - Index: 0
518518; RELOC-NEXT: Name: .bss.colliding_global1
519; RELOC-NEXT: Alignment: 4
519; RELOC-NEXT: Alignment: 2
520520; RELOC-NEXT: Flags: [ ]
521521; RELOC-NEXT: - Index: 1
522522; RELOC-NEXT: Name: .bss.colliding_global2
523; RELOC-NEXT: Alignment: 4
523; RELOC-NEXT: Alignment: 2
524524; RELOC-NEXT: Flags: [ ]
525525; RELOC-NEXT: - Index: 2
526526; RELOC-NEXT: Name: .bss.colliding_global3
527; RELOC-NEXT: Alignment: 4
527; RELOC-NEXT: Alignment: 2
528528; RELOC-NEXT: Flags: [ ]
529529; RELOC-NEXT: - Type: CUSTOM
530530; RELOC-NEXT: Name: name
deps/lld/test/wasm/lto/archive.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: rm -f %t.a
33; RUN: llvm-ar rcs %t.a %t1.o
44; RUN: llvm-as %s -o %t2.o
5; RUN: wasm-ld %t2.o %t.a -o %t3
5; RUN: wasm-ld --export-dynamic %t2.o %t.a -o %t3
66; RUN: obj2yaml %t3 | FileCheck %s
77
88target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
deps/lld/test/wasm/lto/cache.ll+6
......@@ -1,5 +1,7 @@
11; RUN: opt -module-hash -module-summary %s -o %t.o
22; 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
46; RUN: rm -Rf %t.cache && mkdir %t.cache
57; Create two files that would be removed by cache pruning due to age.
......@@ -17,6 +19,10 @@
1719; 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
1820; 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
2026; This should remove it.
2127; 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
2228; RUN: ls %t.cache | count 4
deps/lld/test/wasm/lto/export.ll+3-3
......@@ -29,10 +29,10 @@ entry:
2929; CHECK-NEXT: - Name: __data_end
3030; CHECK-NEXT: Kind: GLOBAL
3131; CHECK-NEXT: Index: 2
32; CHECK-NEXT: - Name: _start
33; CHECK-NEXT: Kind: FUNCTION
34; CHECK-NEXT: Index: 2
3532; CHECK-NEXT: - Name: hidden_function
3633; CHECK-NEXT: Kind: FUNCTION
3734; CHECK-NEXT: Index: 1
35; CHECK-NEXT: - Name: _start
36; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 2
3838; 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:
815815; CHECK-NEXT: Content: '01000000'
816816; CHECK-NEXT: - Type: CUSTOM
817817; CHECK-NEXT: Name: linking
818; CHECK-NEXT: Version: 1
818; CHECK-NEXT: Version: 2
819819; CHECK-NEXT: SymbolTable:
820820; CHECK-NEXT: - Index: 0
821821; CHECK-NEXT: Kind: FUNCTION
......@@ -1482,9 +1482,9 @@ entry:
14821482; CHECK-NEXT: SegmentInfo:
14831483; CHECK-NEXT: - Index: 0
14841484; CHECK-NEXT: Name: .data.g0
1485; CHECK-NEXT: Alignment: 4
1485; CHECK-NEXT: Alignment: 2
14861486; CHECK-NEXT: Flags: [ ]
14871487; CHECK-NEXT: - Index: 1
14881488; CHECK-NEXT: Name: .data.foo
1489; CHECK-NEXT: Alignment: 4
1489; CHECK-NEXT: Alignment: 2
14901490; CHECK-NEXT: Flags: [ ]
deps/lld/test/wasm/relocatable.ll+8-8
......@@ -63,7 +63,7 @@ entry:
6363; CHECK-NEXT: FunctionTypes: [ 2, 1, 1 ]
6464; CHECK-NEXT: - Type: TABLE
6565; CHECK-NEXT: Tables:
66; CHECK-NEXT: - ElemType: ANYFUNC
66; CHECK-NEXT: - ElemType: FUNCREF
6767; CHECK-NEXT: Limits:
6868; CHECK-NEXT: Flags: [ HAS_MAX ]
6969; CHECK-NEXT: Initial: 0x00000004
......@@ -157,7 +157,7 @@ entry:
157157; CHECK-NEXT: Content: '616263'
158158; CHECK-NEXT: - Type: CUSTOM
159159; CHECK-NEXT: Name: linking
160; CHECK-NEXT: Version: 1
160; CHECK-NEXT: Version: 2
161161; CHECK-NEXT: SymbolTable:
162162; CHECK-NEXT: - Index: 0
163163; CHECK-NEXT: Kind: FUNCTION
......@@ -232,27 +232,27 @@ entry:
232232; CHECK-NEXT: SegmentInfo:
233233; CHECK-NEXT: - Index: 0
234234; CHECK-NEXT: Name: .rodata.hello_str
235; CHECK-NEXT: Alignment: 1
235; CHECK-NEXT: Alignment: 0
236236; CHECK-NEXT: Flags: [ ]
237237; CHECK-NEXT: - Index: 1
238238; CHECK-NEXT: Name: .data.func_addr1
239; CHECK-NEXT: Alignment: 4
239; CHECK-NEXT: Alignment: 2
240240; CHECK-NEXT: Flags: [ ]
241241; CHECK-NEXT: - Index: 2
242242; CHECK-NEXT: Name: .data.func_addr2
243; CHECK-NEXT: Alignment: 4
243; CHECK-NEXT: Alignment: 2
244244; CHECK-NEXT: Flags: [ ]
245245; CHECK-NEXT: - Index: 3
246246; CHECK-NEXT: Name: .data.func_addr3
247; CHECK-NEXT: Alignment: 4
247; CHECK-NEXT: Alignment: 2
248248; CHECK-NEXT: Flags: [ ]
249249; CHECK-NEXT: - Index: 4
250250; CHECK-NEXT: Name: .data.data_addr1
251; CHECK-NEXT: Alignment: 8
251; CHECK-NEXT: Alignment: 3
252252; CHECK-NEXT: Flags: [ ]
253253; CHECK-NEXT: - Index: 5
254254; CHECK-NEXT: Name: .rodata.data_comdat
255; CHECK-NEXT: Alignment: 1
255; CHECK-NEXT: Alignment: 0
256256; CHECK-NEXT: Flags: [ ]
257257; CHECK-NEXT: Comdats:
258258; 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:
1414}
1515
1616; CHECK: warning: function signature mismatch: weakFn
17; 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.o
17; 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.o
deps/lld/test/wasm/signature-mismatch.ll+4-4
......@@ -18,9 +18,9 @@ entry:
1818declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
1919
2020; CHECK: error: function signature mismatch: ret32
21; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
22; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
21; CHECK-NEXT: >>> defined as (i32, i64, i32) -> i32 in {{.*}}.main.o
22; CHECK-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
2323
2424; REVERSE: error: function signature mismatch: ret32
25; REVERSE-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
26; REVERSE-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
25; REVERSE-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
26; 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:
3131; CHECK-NEXT: FunctionTypes: [ 0 ]
3232; CHECK-NEXT: - Type: TABLE
3333; CHECK-NEXT: Tables:
34; CHECK-NEXT: - ElemType: ANYFUNC
34; CHECK-NEXT: - ElemType: FUNCREF
3535; CHECK-NEXT: Limits:
3636; CHECK-NEXT: Flags: [ HAS_MAX ]
3737; CHECK-NEXT: Initial: 0x00000001
......@@ -50,7 +50,7 @@ entry:
5050; CHECK-NEXT: Body: 23808080800041106B1A41000B
5151; CHECK-NEXT: - Type: CUSTOM
5252; CHECK-NEXT: Name: linking
53; CHECK-NEXT: Version: 1
53; CHECK-NEXT: Version: 2
5454; CHECK-NEXT: SymbolTable:
5555; CHECK-NEXT: - Index: 0
5656; 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
22RUN: wasm-ld --strip-debug -o %t.wasm %t.start.o
33RUN: 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
59# Check that there is no name section
610CHECK-NOT: Name: name
deps/lld/test/wasm/undefined-entry.test+3-5
......@@ -1,11 +1,9 @@
11RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
22RUN: 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
34RUN: 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: _start
7CHECK-CUSTOM: error: undefined symbol: foo
8CHECK-ALLOW: error: entry symbol not defined (pass --no-entry to supress):
9_start
6CHECK: error: entry symbol not defined (pass --no-entry to supress): _start
7CHECK-CUSTOM: error: entry symbol not defined (pass --no-entry to supress): foo
108
119RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o
deps/lld/test/wasm/undefined-weak-call.ll+2-2
......@@ -1,5 +1,5 @@
11; 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 \
33; RUN: -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
......@@ -45,7 +45,7 @@ define i32 @callWeakFuncs() {
4545; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ]
4646; CHECK-NEXT: - Type: TABLE
4747; CHECK-NEXT: Tables:
48; CHECK-NEXT: - ElemType: ANYFUNC
48; CHECK-NEXT: - ElemType: FUNCREF
4949; CHECK-NEXT: Limits:
5050; CHECK-NEXT: Flags: [ HAS_MAX ]
5151; CHECK-NEXT: Initial: 0x00000001
deps/lld/test/wasm/undefined.ll+2-2
......@@ -1,10 +1,10 @@
11; RUN: llc -filetype=obj %s -o %t.o
22; 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'
55; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s
66; CHECK: error: {{.*}}.o: undefined symbol: foo
7; CHECK: error: undefined symbol: baz
7; CHECK-NOT: undefined symbol: baz
88
99; Succeeds if we pass a file containing 'foo' as --allow-undefined-file.
1010; RUN: echo 'foo' > %t.txt
deps/lld/test/wasm/visibility-hidden.ll+30-6
......@@ -1,11 +1,18 @@
11; RUN: llc -filetype=obj -o %t.o %s
22; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o
3; RUN: rm -f %t2.a
34; RUN: llvm-ar rcs %t2.a %t2.o
4; RUN: wasm-ld %t.o %t2.a -o %t.wasm
5
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
59; RUN: obj2yaml %t.wasm | FileCheck %s
610
7; Test that hidden symbols are not exported, whether pulled in from an archive
8; or directly.
11; Test that symbols with default visitiblity are not exported without
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
1017target triple = "wasm32-unknown-unknown"
1118
......@@ -42,13 +49,30 @@ entry:
4249; CHECK-NEXT: - Name: __data_end
4350; CHECK-NEXT: Kind: GLOBAL
4451; CHECK-NEXT: Index: 2
45; CHECK-NEXT: - Name: _start
46; CHECK-NEXT: Kind: FUNCTION
47; CHECK-NEXT: Index: 3
4852; CHECK-NEXT: - Name: objectDefault
4953; CHECK-NEXT: Kind: FUNCTION
5054; CHECK-NEXT: Index: 2
55; CHECK-NEXT: - Name: _start
56; CHECK-NEXT: Kind: FUNCTION
57; CHECK-NEXT: Index: 3
5158; CHECK-NEXT: - Name: archiveDefault
5259; CHECK-NEXT: Kind: FUNCTION
5360; CHECK-NEXT: Index: 5
5461; 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 @@
11; RUN: llc -filetype=obj -o %t.o %s
22; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
3; RUN: wasm-ld %t.o %t2.o -o %t.wasm
3; RUN: wasm-ld --export-dynamic %t.o %t2.o -o %t.wasm
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
66; Test that the strongly defined alias_fn from this file is used both here
......@@ -35,7 +35,7 @@ entry:
3535; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ]
3636; CHECK-NEXT: - Type: TABLE
3737; CHECK-NEXT: Tables:
38; CHECK-NEXT: - ElemType: ANYFUNC
38; CHECK-NEXT: - ElemType: FUNCREF
3939; CHECK-NEXT: Limits:
4040; CHECK-NEXT: Flags: [ HAS_MAX ]
4141; CHECK-NEXT: Initial: 0x00000003
......@@ -74,12 +74,12 @@ entry:
7474; CHECK-NEXT: - Name: __data_end
7575; CHECK-NEXT: Kind: GLOBAL
7676; CHECK-NEXT: Index: 2
77; CHECK-NEXT: - Name: _start
78; CHECK-NEXT: Kind: FUNCTION
79; CHECK-NEXT: Index: 2
8077; CHECK-NEXT: - Name: alias_fn
8178; CHECK-NEXT: Kind: FUNCTION
8279; CHECK-NEXT: Index: 1
80; CHECK-NEXT: - Name: _start
81; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 2
8383; CHECK-NEXT: - Name: direct_fn
8484; CHECK-NEXT: Kind: FUNCTION
8585; CHECK-NEXT: Index: 3
deps/lld/test/wasm/weak-alias.ll+4-4
......@@ -1,6 +1,6 @@
11; RUN: llc -filetype=obj -o %t.o %s
22; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
3; RUN: wasm-ld %t.o %t2.o -o %t.wasm
3; RUN: wasm-ld --export-dynamic %t.o %t2.o -o %t.wasm
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
66; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly
......@@ -32,7 +32,7 @@ entry:
3232; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1, 1 ]
3333; CHECK-NEXT: - Type: TABLE
3434; CHECK-NEXT: Tables:
35; CHECK-NEXT: - ElemType: ANYFUNC
35; CHECK-NEXT: - ElemType: FUNCREF
3636; CHECK-NEXT: Limits:
3737; CHECK-NEXT: Flags: [ HAS_MAX ]
3838; CHECK-NEXT: Initial: 0x00000002
......@@ -170,7 +170,7 @@ entry:
170170; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]
171171; RELOC-NEXT: - Type: TABLE
172172; RELOC-NEXT: Tables:
173; RELOC-NEXT: - ElemType: ANYFUNC
173; RELOC-NEXT: - ElemType: FUNCREF
174174; RELOC-NEXT: Limits:
175175; RELOC-NEXT: Flags: [ HAS_MAX ]
176176; RELOC-NEXT: Initial: 0x00000002
......@@ -250,7 +250,7 @@ entry:
250250; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
251251; RELOC-NEXT: - Type: CUSTOM
252252; RELOC-NEXT: Name: linking
253; RELOC-NEXT: Version: 1
253; RELOC-NEXT: Version: 2
254254; RELOC-NEXT: SymbolTable:
255255; RELOC-NEXT: - Index: 0
256256; RELOC-NEXT: Kind: FUNCTION
deps/lld/test/wasm/weak-symbols.ll+6-11
......@@ -1,7 +1,7 @@
11; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o
22; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o
33; RUN: llc -filetype=obj %s -o %t.o
4; RUN: wasm-ld -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o
4; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
55; RUN: obj2yaml %t.wasm | FileCheck %s
66
77target triple = "wasm32-unknown-unknown"
......@@ -29,10 +29,10 @@ entry:
2929; CHECK-NEXT: ReturnType: I32
3030; CHECK-NEXT: ParamTypes:
3131; CHECK-NEXT: - Type: FUNCTION
32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1 ]
32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1 ]
3333; CHECK-NEXT: - Type: TABLE
3434; CHECK-NEXT: Tables:
35; CHECK-NEXT: - ElemType: ANYFUNC
35; CHECK-NEXT: - ElemType: FUNCREF
3636; CHECK-NEXT: Limits:
3737; CHECK-NEXT: Flags: [ HAS_MAX ]
3838; CHECK-NEXT: Initial: 0x00000002
......@@ -59,7 +59,7 @@ entry:
5959; CHECK-NEXT: Mutable: false
6060; CHECK-NEXT: InitExpr:
6161; CHECK-NEXT: Opcode: I32_CONST
62; CHECK-NEXT: Value: 1032
62; CHECK-NEXT: Value: 1028
6363; CHECK-NEXT: - Index: 3
6464; CHECK-NEXT: Type: I32
6565; CHECK-NEXT: Mutable: false
......@@ -91,7 +91,7 @@ entry:
9191; CHECK-NEXT: Index: 3
9292; CHECK-NEXT: - Name: exportWeak2
9393; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 5
94; CHECK-NEXT: Index: 4
9595; CHECK-NEXT: - Type: ELEM
9696; CHECK-NEXT: Segments:
9797; CHECK-NEXT: - Offset:
......@@ -114,9 +114,6 @@ entry:
114114; CHECK-NEXT: Body: 4181808080000B
115115; CHECK-NEXT: - Index: 4
116116; CHECK-NEXT: Locals:
117; CHECK-NEXT: Body: 41020B
118; CHECK-NEXT: - Index: 5
119; CHECK-NEXT: Locals:
120117; CHECK-NEXT: Body: 4181808080000B
121118; CHECK-NEXT: - Type: DATA
122119; CHECK-NEXT: Segments:
......@@ -125,7 +122,7 @@ entry:
125122; CHECK-NEXT: Offset:
126123; CHECK-NEXT: Opcode: I32_CONST
127124; CHECK-NEXT: Value: 1024
128; CHECK-NEXT: Content: '0100000002000000'
125; CHECK-NEXT: Content: '01000000'
129126; CHECK-NEXT: - Type: CUSTOM
130127; CHECK-NEXT: Name: name
131128; CHECK-NEXT: FunctionNames:
......@@ -138,7 +135,5 @@ entry:
138135; CHECK-NEXT: - Index: 3
139136; CHECK-NEXT: Name: exportWeak1
140137; CHECK-NEXT: - Index: 4
141; CHECK-NEXT: Name: weakFn
142; CHECK-NEXT: - Index: 5
143138; CHECK-NEXT: Name: exportWeak2
144139; CHECK-NEXT: ...
deps/lld/test/wasm/weak-undefined.ll+4-9
......@@ -22,7 +22,8 @@ define i32* @get_address_of_global_var() #0 {
2222
2323define void @_start() #0 {
2424entry:
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()
2627 ret void
2728}
2829
......@@ -42,7 +43,7 @@ entry:
4243; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ]
4344; CHECK-NEXT: - Type: TABLE
4445; CHECK-NEXT: Tables:
45; CHECK-NEXT: - ElemType: ANYFUNC
46; CHECK-NEXT: - ElemType: FUNCREF
4647; CHECK-NEXT: Limits:
4748; CHECK-NEXT: Flags: [ HAS_MAX ]
4849; CHECK-NEXT: Initial: 0x00000001
......@@ -84,12 +85,6 @@ entry:
8485; CHECK-NEXT: - Name: _start
8586; CHECK-NEXT: Kind: FUNCTION
8687; 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
9388; CHECK-NEXT: - Type: CODE
9489; CHECK-NEXT: Functions:
9590; CHECK-NEXT: - Index: 0
......@@ -103,5 +98,5 @@ entry:
10398; CHECK-NEXT: Body: 4180808080000B
10499; CHECK-NEXT: - Index: 3
105100; CHECK-NEXT: Locals:
106; CHECK-NEXT: Body: 1082808080001A0B
101; CHECK-NEXT: Body: 1082808080001A1081808080001A0B
107102; CHECK-NEXT: ...
deps/lld/tools/lld/lld.cpp+1-1
......@@ -138,7 +138,7 @@ int main(int Argc, const char **Argv) {
138138 return !wasm::link(Args, canExitEarly());
139139 default:
140140 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"
142142 " (WebAssembly) instead");
143143 }
144144}
deps/lld/wasm/Config.h+8-1
......@@ -20,18 +20,22 @@ namespace wasm {
2020
2121struct Configuration {
2222 bool AllowUndefined;
23 bool CompressRelocTargets;
23 bool CompressRelocations;
2424 bool Demangle;
2525 bool DisableVerify;
2626 bool ExportAll;
27 bool ExportDynamic;
2728 bool ExportTable;
2829 bool GcSections;
2930 bool ImportMemory;
31 bool SharedMemory;
3032 bool ImportTable;
3133 bool MergeDataSegments;
34 bool Pie;
3235 bool PrintGcSections;
3336 bool Relocatable;
3437 bool SaveTemps;
38 bool Shared;
3539 bool StripAll;
3640 bool StripDebug;
3741 bool StackFirst;
......@@ -50,6 +54,9 @@ struct Configuration {
5054 llvm::StringSet<> AllowUndefinedSymbols;
5155 std::vector<llvm::StringRef> SearchPaths;
5256 llvm::CachePruningPolicy ThinLTOCachePolicy;
57
58 // True if we are creating position-independent code.
59 bool Pic;
5360};
5461
5562// The only instance of Configuration struct.
deps/lld/wasm/Driver.cpp+184-104
......@@ -31,6 +31,7 @@
3131#define DEBUG_TYPE "lld"
3232
3333using namespace llvm;
34using namespace llvm::object;
3435using namespace llvm::sys;
3536using namespace llvm::wasm;
3637
......@@ -78,7 +79,7 @@ private:
7879
7980bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
8081 raw_ostream &Error) {
81 errorHandler().LogName = sys::path::filename(Args[0]);
82 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
8283 errorHandler().ErrorOS = &Error;
8384 errorHandler().ColorDiagnostics = Error.has_colors();
8485 errorHandler().ErrorLimitExceededMsg =
......@@ -186,8 +187,7 @@ static void readImportFile(StringRef Filename) {
186187
187188// Returns slices of MB by parsing MB as an archive file.
188189// Each slice consists of a member file in the archive.
189std::vector<MemoryBufferRef> static getArchiveMembers(
190 MemoryBufferRef MB) {
190std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) {
191191 std::unique_ptr<Archive> File =
192192 CHECK(Archive::create(MB),
193193 MB.getBufferIdentifier() + ": failed to parse archive");
......@@ -205,8 +205,8 @@ std::vector<MemoryBufferRef> static getArchiveMembers(
205205 V.push_back(MBRef);
206206 }
207207 if (Err)
208 fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
209 toString(std::move(Err)));
208 fatal(MB.getBufferIdentifier() +
209 ": Archive::children failed: " + toString(std::move(Err)));
210210
211211 // Take ownership of memory buffers created for members of thin archives.
212212 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
......@@ -306,17 +306,14 @@ static void handleWeakUndefines() {
306306
307307 // It is possible for undefined functions not to have a signature (eg. if
308308 // added via "--undefined"), but weak undefined ones do have a signature.
309 assert(FuncSym->FunctionType);
310 const WasmSignature &Sig = *FuncSym->FunctionType;
309 assert(FuncSym->Signature);
310 const WasmSignature &Sig = *FuncSym->Signature;
311311
312312 // Add a synthetic dummy for weak undefined functions. These dummies will
313313 // be GC'd if not used as the target of any "call" instructions.
314 Optional<std::string> SymName = demangleItanium(Sym->getName());
315 StringRef DebugName =
316 Saver.save("undefined function " +
317 (SymName ? StringRef(*SymName) : Sym->getName()));
318 SyntheticFunction *Func =
319 make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
314 std::string SymName = toString(*Sym);
315 StringRef DebugName = Saver.save("undefined function " + SymName);
316 auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
320317 Func->setBody(UnreachableFn);
321318 // Ensure it compares equal to the null pointer, and so that table relocs
322319 // don't pull in the stub body (only call-operand relocs should do that).
......@@ -328,51 +325,24 @@ static void handleWeakUndefines() {
328325 }
329326}
330327
331// Force Sym to be entered in the output. Used for -u or equivalent.
332static Symbol *addUndefined(StringRef Name) {
333 Symbol *S = Symtab->addUndefinedFunction(Name, 0, nullptr, nullptr);
334
335 // Since symbol S may not be used inside the program, LTO may
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
328// Some Config members do not directly correspond to any particular
329// command line options, but computed based on other Config values.
330// This function initialize such members. See Config.h for the details
331// of these values.
332static void setConfigs(opt::InputArgList &Args) {
367333 Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
334 Config->CompressRelocations = Args.hasArg(OPT_compress_relocations);
368335 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
369336 Config->DisableVerify = Args.hasArg(OPT_disable_verify);
370337 Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
371338 Config->ExportAll = Args.hasArg(OPT_export_all);
339 Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic,
340 OPT_no_export_dynamic, false);
372341 Config->ExportTable = Args.hasArg(OPT_export_table);
373342 errorHandler().FatalWarnings =
374343 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
375344 Config->ImportMemory = Args.hasArg(OPT_import_memory);
345 Config->SharedMemory = Args.hasArg(OPT_shared_memory);
376346 Config->ImportTable = Args.hasArg(OPT_import_table);
377347 Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
378348 Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
......@@ -384,10 +354,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
384354 Config->MergeDataSegments =
385355 Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
386356 !Config->Relocatable);
357 Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
387358 Config->PrintGcSections =
388359 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
389360 Config->SaveTemps = Args.hasArg(OPT_save_temps);
390361 Config->SearchPaths = args::getStrings(Args, OPT_L);
362 Config->Shared = Args.hasArg(OPT_shared);
391363 Config->StripAll = Args.hasArg(OPT_strip_all);
392364 Config->StripDebug = Args.hasArg(OPT_strip_debug);
393365 Config->StackFirst = Args.hasArg(OPT_stack_first);
......@@ -404,8 +376,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
404376 Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
405377 Config->ZStackSize =
406378 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
410388 if (Config->LTOO > 3)
411389 error("invalid optimization level for LTO: " + Twine(Config->LTOO));
......@@ -414,13 +392,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
414392 if (Config->ThinLTOJobs == 0)
415393 error("--thinlto-jobs: number of threads must be > 0");
416394
417 if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
418 readImportFile(Arg->getValue());
419
420 if (!Args.hasArg(OPT_INPUT)) {
421 error("no input files");
422 return;
423 }
395 if (Config->Pie && Config->Shared)
396 error("-shared and -pie may not be used together");
424397
425398 if (Config->OutputFile.empty())
426399 error("no output file specified");
......@@ -433,46 +406,151 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
433406 error("entry point specified for relocatable output file");
434407 if (Config->GcSections)
435408 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");
436411 if (Args.hasArg(OPT_undefined))
437412 error("-r -and --undefined may not be used together");
413 if (Config->Pie)
414 error("-r and -pie may not be used together");
438415 }
416}
439417
440 Symbol *EntrySym = nullptr;
441 if (!Config->Relocatable) {
418// Force Sym to be entered in the output. Used for -u or equivalent.
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 {
442461 llvm::wasm::WasmGlobal Global;
443462 Global.Type = {WASM_TYPE_I32, true};
444463 Global.InitExpr.Value.Int32 = 0;
445464 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
446465 Global.SymbolName = "__stack_pointer";
447 InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr);
466 auto *StackPointer = make<InputGlobal>(Global, nullptr);
448467 StackPointer->Live = true;
449
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"));
468 // For non-PIC code
456469 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
457470 // spec proposal is implemented in all major browsers.
458471 // See: https://github.com/WebAssembly/mutable-global
459472 WasmSym::StackPointer = Symtab->addSyntheticGlobal(
460473 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
461474 WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);
462 WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
463 "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
464475 WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
465476
466 // For now, since we don't actually use the start function as the
467 // wasm start symbol, we don't need to care about it signature.
468 if (!Config->Entry.empty())
469 EntrySym = addUndefined(Config->Entry);
477 // These two synthetic symbols exist purely for the embedder so we always
478 // want to export them.
479 WasmSym::HeapBase->ForceExport = true;
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.
472 for (auto *Arg : Args.filtered(OPT_undefined))
473 addUndefined(Arg->getValue());
512 // Handle --version
513 if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
514 outs() << getLLDVersion() << "\n";
515 return;
474516 }
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
476554 createFiles(Args);
477555 if (errorCount())
478556 return;
......@@ -484,44 +562,46 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
484562 if (errorCount())
485563 return;
486564
487 // Add synthetic dummies for weak undefined functions.
488 if (!Config->Relocatable)
489 handleWeakUndefines();
565 // Handle the `--undefined <sym>` options.
566 for (auto *Arg : Args.filtered(OPT_undefined))
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
492571 for (auto *Arg : Args.filtered(OPT_export)) {
493 StringRef Name = Arg->getValue();
494 Symbol *Sym = Symtab->find(Name);
572 Symbol *Sym = handleUndefined(Arg->getValue());
495573 if (Sym && Sym->isDefined())
496574 Sym->ForceExport = true;
497575 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());
499578 }
500579
501 // Do link-time optimization if given files are LLVM bitcode files.
502 // This compiles bitcode files into real object files.
503 Symtab->addCombinedLTOObject();
504 if (errorCount())
505 return;
580 Symbol *EntrySym = nullptr;
581 if (!Config->Relocatable) {
582 // Add synthetic dummies for weak undefined functions.
583 handleWeakUndefines();
506584
507 // Make sure we have resolved all symbols.
508 if (!Config->Relocatable && !Config->AllowUndefined) {
509 Symtab->reportRemainingUndefines();
510 } else {
511 // Even when using --allow-undefined we still want to report the absence of
512 // our initial set of undefined symbols (i.e. the entry point and symbols
513 // specified via --undefined).
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());
585 if (!Config->Shared && !Config->Entry.empty()) {
586 EntrySym = handleUndefined(Config->Entry);
587 if (EntrySym && EntrySym->isDefined())
588 EntrySym->ForceExport = true;
589 else
590 error("entry symbol not defined (pass --no-entry to supress): " +
591 Config->Entry);
520592 }
521 if (EntrySym && !EntrySym->isDefined())
522 error("entry symbol not defined (pass --no-entry to supress): " +
523 EntrySym->getName());
593
594 // Make sure we have resolved all symbols.
595 if (!Config->AllowUndefined)
596 Symtab->reportRemainingUndefines();
524597 }
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();
525605 if (errorCount())
526606 return;
527607
deps/lld/wasm/InputChunks.cpp+12-15
......@@ -25,7 +25,9 @@ using namespace lld::wasm;
2525
2626static StringRef ReloctTypeToString(uint8_t RelocType) {
2727 switch (RelocType) {
28#define WASM_RELOC(NAME, REL) case REL: return #NAME;
28#define WASM_RELOC(NAME, REL) \
29 case REL: \
30 return #NAME;
2931#include "llvm/BinaryFormat/WasmRelocs.def"
3032#undef WASM_RELOC
3133 }
......@@ -43,16 +45,6 @@ StringRef InputChunk::getComdatName() const {
4345 return File->getWasmObj()->linkingData().Comdats[Index];
4446}
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
5648void InputChunk::verifyRelocTargets() const {
5749 for (const WasmRelocation &Rel : Relocations) {
5850 uint32_t ExistingValue;
......@@ -63,6 +55,7 @@ void InputChunk::verifyRelocTargets() const {
6355 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
6456 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
6557 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
58 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
6659 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
6760 ExistingValue = decodeULEB128(Loc, &BytesRead);
6861 break;
......@@ -119,6 +112,7 @@ void InputChunk::writeTo(uint8_t *Buf) const {
119112 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
120113 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
121114 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
115 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
122116 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
123117 encodeULEB128(Value, Loc, 5);
124118 break;
......@@ -188,6 +182,7 @@ static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
188182 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
189183 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
190184 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
185 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
191186 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
192187 return encodeULEB128(Value, Buf);
193188 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
......@@ -203,6 +198,7 @@ static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {
203198 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
204199 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
205200 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
201 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
206202 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
207203 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
208204 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
......@@ -228,7 +224,7 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {
228224// This function only computes the final output size. It must be called
229225// before getSize() is used to calculate of layout of the code section.
230226void InputFunction::calculateSize() {
231 if (!File || !Config->CompressRelocTargets)
227 if (!File || !Config->CompressRelocations)
232228 return;
233229
234230 LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");
......@@ -242,7 +238,7 @@ void InputFunction::calculateSize() {
242238 uint32_t End = Start + Function->Size;
243239
244240 uint32_t LastRelocEnd = Start + FunctionSizeLength;
245 for (WasmRelocation &Rel : Relocations) {
241 for (const WasmRelocation &Rel : Relocations) {
246242 LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n");
247243 CompressedFuncSize += Rel.Offset - LastRelocEnd;
248244 CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));
......@@ -263,11 +259,12 @@ void InputFunction::calculateSize() {
263259// Override the default writeTo method so that we can (optionally) write the
264260// compressed version of the function.
265261void InputFunction::writeTo(uint8_t *Buf) const {
266 if (!File || !Config->CompressRelocTargets)
262 if (!File || !Config->CompressRelocations)
267263 return InputChunk::writeTo(Buf);
268264
269265 Buf += OutputOffset;
270 uint8_t *Orig = Buf; (void)Orig;
266 uint8_t *Orig = Buf;
267 (void)Orig;
271268
272269 const uint8_t *SecStart = File->CodeSection->Content.data();
273270 const uint8_t *FuncStart = SecStart + getInputSectionOffset();
deps/lld/wasm/InputChunks.h+14-26
......@@ -24,18 +24,9 @@
2424#include "Config.h"
2525#include "InputFiles.h"
2626#include "lld/Common/ErrorHandler.h"
27#include "lld/Common/LLVM.h"
2728#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
3930namespace lld {
4031namespace wasm {
4132
......@@ -49,17 +40,18 @@ public:
4940 Kind kind() const { return SectionKind; }
5041
5142 virtual uint32_t getSize() const { return data().size(); }
52
53 void copyRelocations(const WasmSection &Section);
43 virtual uint32_t getInputSize() const { return getSize(); };
5444
5545 virtual void writeTo(uint8_t *SectionStart) const;
5646
5747 ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
48 void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; }
5849
5950 virtual StringRef getName() const = 0;
6051 virtual StringRef getDebugName() const = 0;
6152 virtual uint32_t getComdat() const = 0;
6253 StringRef getComdatName() const;
54 virtual uint32_t getInputSectionOffset() const = 0;
6355
6456 size_t NumRelocations() const { return Relocations.size(); }
6557 void writeRelocations(llvm::raw_ostream &OS) const;
......@@ -77,14 +69,12 @@ protected:
7769 : File(F), Live(!Config->GcSections), SectionKind(K) {}
7870 virtual ~InputChunk() = default;
7971 virtual ArrayRef<uint8_t> data() const = 0;
80 virtual uint32_t getInputSectionOffset() const = 0;
81 virtual uint32_t getInputSize() const { return getSize(); };
8272
8373 // Verifies the existing data at relocation targets matches our expectations.
8474 // This is performed only debug builds as an extra sanity check.
8575 void verifyRelocTargets() const;
8676
87 std::vector<WasmRelocation> Relocations;
77 ArrayRef<WasmRelocation> Relocations;
8878 Kind SectionKind;
8979};
9080
......@@ -107,15 +97,15 @@ public:
10797 StringRef getName() const override { return Segment.Data.Name; }
10898 StringRef getDebugName() const override { return StringRef(); }
10999 uint32_t getComdat() const override { return Segment.Data.Comdat; }
100 uint32_t getInputSectionOffset() const override {
101 return Segment.SectionOffset;
102 }
110103
111104 const OutputSegment *OutputSeg = nullptr;
112105 int32_t OutputSegmentOffset = 0;
113106
114107protected:
115108 ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }
116 uint32_t getInputSectionOffset() const override {
117 return Segment.SectionOffset;
118 }
119109
120110 const WasmSegment &Segment;
121111};
......@@ -139,15 +129,19 @@ public:
139129 uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
140130 uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
141131 uint32_t getSize() const override {
142 if (Config->CompressRelocTargets && File) {
132 if (Config->CompressRelocations && File) {
143133 assert(CompressedSize);
144134 return CompressedSize;
145135 }
146136 return data().size();
147137 }
138 uint32_t getInputSize() const override { return Function->Size; }
148139 uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
149140 bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
150141 void setFunctionIndex(uint32_t Index);
142 uint32_t getInputSectionOffset() const override {
143 return Function->CodeSectionOffset;
144 }
151145 uint32_t getTableIndex() const { return TableIndex.getValue(); }
152146 bool hasTableIndex() const { return TableIndex.hasValue(); }
153147 void setTableIndex(uint32_t Index);
......@@ -162,17 +156,11 @@ public:
162156
163157protected:
164158 ArrayRef<uint8_t> data() const override {
165 assert(!Config->CompressRelocTargets);
159 assert(!Config->CompressRelocations);
166160 return File->CodeSection->Content.slice(getInputSectionOffset(),
167161 Function->Size);
168162 }
169163
170 uint32_t getInputSize() const override { return Function->Size; }
171
172 uint32_t getInputSectionOffset() const override {
173 return Function->CodeSectionOffset;
174 }
175
176164 const WasmFunction *Function;
177165 llvm::Optional<uint32_t> FunctionIndex;
178166 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 @@
1010#include "InputFiles.h"
1111#include "Config.h"
1212#include "InputChunks.h"
13#include "InputEvent.h"
1314#include "InputGlobal.h"
1415#include "SymbolTable.h"
1516#include "lld/Common/ErrorHandler.h"
......@@ -57,12 +58,13 @@ void ObjFile::dumpInfo() const {
5758 log("info for: " + getName() +
5859 "\n Symbols : " + Twine(Symbols.size()) +
5960 "\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()));
6163}
6264
6365// Relocations contain either symbol or type indices. This function takes a
6466// 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).
6668uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
6769 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
6870 assert(TypeIsUsed[Reloc.Index]);
......@@ -94,16 +96,17 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
9496 switch (Reloc.Type) {
9597 case R_WEBASSEMBLY_TABLE_INDEX_I32:
9698 case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
97 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
99 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
98100 return TableEntries[Sym.Info.ElementIndex];
99101 }
100102 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
101103 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
102104 case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
103 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
105 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
104106 if (Sym.isUndefined())
105107 return 0;
106 const WasmSegment& Segment = WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
108 const WasmSegment &Segment =
109 WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
107110 return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
108111 Reloc.Addend;
109112 }
......@@ -118,8 +121,9 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
118121 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
119122 return Reloc.Index;
120123 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
121 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: {
122 const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
124 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
125 case R_WEBASSEMBLY_EVENT_INDEX_LEB: {
126 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
123127 return Sym.Info.ElementIndex;
124128 }
125129 default:
......@@ -146,10 +150,13 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
146150 return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
147151 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
148152 return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
153 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
154 return getEventSymbol(Reloc.Index)->getEventIndex();
149155 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
150156 if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
151 return Sym->Function->OutputOffset +
152 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
157 if (Sym->isLive())
158 return Sym->Function->OutputOffset +
159 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
153160 }
154161 return 0;
155162 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
......@@ -159,6 +166,37 @@ uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
159166 }
160167}
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
162200void ObjFile::parse() {
163201 // Parse a memory buffer as a wasm file.
164202 LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
......@@ -200,7 +238,7 @@ void ObjFile::parse() {
200238 DataSection = &Section;
201239 } else if (Section.Type == WASM_SEC_CUSTOM) {
202240 CustomSections.emplace_back(make<InputSection>(Section, this));
203 CustomSections.back()->copyRelocations(Section);
241 CustomSections.back()->setRelocations(Section.Relocations);
204242 CustomSectionsByIndex[SectionIndex] = CustomSections.back();
205243 }
206244 SectionIndex++;
......@@ -215,11 +253,9 @@ void ObjFile::parse() {
215253 UsedComdats[I] = Symtab->addComdat(Comdats[I]);
216254
217255 // Populate `Segments`.
218 for (const WasmSegment &S : WasmObj->dataSegments()) {
219 InputSegment *Seg = make<InputSegment>(S, this);
220 Seg->copyRelocations(*DataSection);
221 Segments.emplace_back(Seg);
222 }
256 for (const WasmSegment &S : WasmObj->dataSegments())
257 Segments.emplace_back(make<InputSegment>(S, this));
258 setRelocs(Segments, DataSection);
223259
224260 // Populate `Functions`.
225261 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
......@@ -227,17 +263,19 @@ void ObjFile::parse() {
227263 ArrayRef<WasmSignature> Types = WasmObj->types();
228264 Functions.reserve(Funcs.size());
229265
230 for (size_t I = 0, E = Funcs.size(); I != E; ++I) {
231 InputFunction *F =
232 make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this);
233 F->copyRelocations(*CodeSection);
234 Functions.emplace_back(F);
235 }
266 for (size_t I = 0, E = Funcs.size(); I != E; ++I)
267 Functions.emplace_back(
268 make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this));
269 setRelocs(Functions, CodeSection);
236270
237271 // Populate `Globals`.
238272 for (const WasmGlobal &G : WasmObj->globals())
239273 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
241279 // Populate `Symbols` based on the WasmSymbols in the object.
242280 Symbols.reserve(WasmObj->getNumberOfSymbols());
243281 for (const SymbolRef &Sym : WasmObj->symbols()) {
......@@ -264,6 +302,10 @@ GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
264302 return cast<GlobalSymbol>(Symbols[Index]);
265303}
266304
305EventSymbol *ObjFile::getEventSymbol(uint32_t Index) const {
306 return cast<EventSymbol>(Symbols[Index]);
307}
308
267309SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const {
268310 return cast<SectionSymbol>(Symbols[Index]);
269311}
......@@ -318,6 +360,13 @@ Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {
318360 assert(Sym.isBindingLocal());
319361 return make<SectionSymbol>(Name, Flags, Section, this);
320362 }
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 }
321370 }
322371 llvm_unreachable("unknown symbol kind");
323372}
......@@ -328,7 +377,7 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
328377
329378 switch (Sym.Info.Kind) {
330379 case WASM_SYMBOL_TYPE_FUNCTION:
331 return Symtab->addUndefinedFunction(Name, Flags, this, Sym.FunctionType);
380 return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature);
332381 case WASM_SYMBOL_TYPE_DATA:
333382 return Symtab->addUndefinedData(Name, Flags, this);
334383 case WASM_SYMBOL_TYPE_GLOBAL:
deps/lld/wasm/InputFiles.h+5-17
......@@ -20,21 +20,6 @@
2020#include "llvm/Support/MemoryBuffer.h"
2121#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
3823namespace lld {
3924namespace wasm {
4025
......@@ -42,6 +27,7 @@ class InputChunk;
4227class InputFunction;
4328class InputSegment;
4429class InputGlobal;
30class InputEvent;
4531class InputSection;
4632
4733class InputFile {
......@@ -84,12 +70,12 @@ public:
8470 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
8571 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
8975 void parse() override;
9076
9177private:
92 std::unique_ptr<Archive> File;
78 std::unique_ptr<llvm::object::Archive> File;
9379 llvm::DenseSet<uint64_t> Seen;
9480};
9581
......@@ -123,6 +109,7 @@ public:
123109 std::vector<InputSegment *> Segments;
124110 std::vector<InputFunction *> Functions;
125111 std::vector<InputGlobal *> Globals;
112 std::vector<InputEvent *> Events;
126113 std::vector<InputSection *> CustomSections;
127114 llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex;
128115
......@@ -131,6 +118,7 @@ public:
131118 DataSymbol *getDataSymbol(uint32_t Index) const;
132119 GlobalSymbol *getGlobalSymbol(uint32_t Index) const;
133120 SectionSymbol *getSectionSymbol(uint32_t Index) const;
121 EventSymbol *getEventSymbol(uint32_t Index) const;
134122
135123private:
136124 Symbol *createDefined(const WasmSymbol &Sym);
deps/lld/wasm/InputGlobal.h-3
......@@ -16,9 +16,6 @@
1616#include "lld/Common/ErrorHandler.h"
1717#include "llvm/Object/Wasm.h"
1818
19using llvm::wasm::WasmGlobal;
20using llvm::wasm::WasmInitExpr;
21
2219namespace lld {
2320namespace wasm {
2421
deps/lld/wasm/LTO.cpp+12-5
......@@ -36,8 +36,6 @@
3636#include <vector>
3737
3838using namespace llvm;
39using namespace llvm::object;
40
4139using namespace lld;
4240using namespace lld::wasm;
4341
......@@ -55,6 +53,14 @@ static std::unique_ptr<lto::LTO> createLTO() {
5553 C.DisableVerify = Config->DisableVerify;
5654 C.DiagHandler = diagnosticHandler;
5755 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
5965 if (Config->SaveTemps)
6066 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
......@@ -72,10 +78,11 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
7278BitcodeCompiler::~BitcodeCompiler() = default;
7379
7480static void undefine(Symbol *S) {
75 if (isa<DefinedFunction>(S))
76 replaceSymbol<UndefinedFunction>(S, S->getName(), 0);
81 if (auto F = dyn_cast<DefinedFunction>(S))
82 replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
83 F->Signature);
7784 else if (isa<DefinedData>(S))
78 replaceSymbol<UndefinedData>(S, S->getName(), 0);
85 replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
7986 else
8087 llvm_unreachable("unexpected symbol kind");
8188}
deps/lld/wasm/MarkLive.cpp+4-2
......@@ -22,6 +22,7 @@
2222#include "MarkLive.h"
2323#include "Config.h"
2424#include "InputChunks.h"
25#include "InputEvent.h"
2526#include "InputGlobal.h"
2627#include "SymbolTable.h"
2728#include "Symbols.h"
......@@ -30,8 +31,6 @@
3031
3132using namespace llvm;
3233using namespace llvm::wasm;
33using namespace lld;
34using namespace lld::wasm;
3534
3635void lld::wasm::markLive() {
3736 if (!Config->GcSections)
......@@ -107,6 +106,9 @@ void lld::wasm::markLive() {
107106 for (InputGlobal *G : Obj->Globals)
108107 if (!G->Live)
109108 message("removing unused section " + toString(G));
109 for (InputEvent *E : Obj->Events)
110 if (!E->Live)
111 message("removing unused section " + toString(E));
110112 }
111113 for (InputChunk *C : Symtab->SyntheticFunctions)
112114 if (!C->Live)
deps/lld/wasm/Options.td+33-16
......@@ -6,9 +6,10 @@ class F<string name>: Flag<["--", "-"], name>;
66class J<string name>: Joined<["--", "-"], name>;
77class S<string name>: Separate<["--", "-"], name>;
88
9multiclass Eq<string name> {
10 def "": Separate<["--", "-"], name>;
11 def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>;
9multiclass Eq<string name, string help> {
10 def NAME: Separate<["--", "-"], name>;
11 def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>,
12 HelpText<help>;
1213}
1314
1415multiclass B<string name, string help1, string help2> {
......@@ -16,17 +17,24 @@ multiclass B<string name, string help1, string help2> {
1617 def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
1718}
1819
19// The follow flags are shared with the ELF linker
20// The following flags are shared with the ELF linker
2021def color_diagnostics: F<"color-diagnostics">,
2122 HelpText<"Use colors in diagnostics">;
2223
2324def color_diagnostics_eq: J<"color-diagnostics=">,
2425 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
2630defm demangle: B<"demangle",
2731 "Demangle symbol names",
2832 "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
3038def entry: S<"entry">, MetaVarName<"<entry>">,
3139 HelpText<"Name of entry point symbol">;
3240
......@@ -67,20 +75,25 @@ def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
6775
6876def 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
7082defm print_gc_sections: B<"print-gc-sections",
7183 "List removed unused sections",
7284 "Do not list removed unused sections">;
7385
7486def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
7587
88def shared: F<"shared">, HelpText<"Build a shared object">;
89
7690def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
7791
7892def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
7993
8094def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
8195
82defm undefined: Eq<"undefined">,
83 HelpText<"Force undefined symbol during linking">;
96defm undefined: Eq<"undefined", "Force undefined symbol during linking">;
8497
8598def v: Flag<["-"], "v">, HelpText<"Display the version number">;
8699
......@@ -102,8 +115,7 @@ def allow_undefined_file: J<"allow-undefined-file=">,
102115def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">,
103116 Alias<allow_undefined_file>;
104117
105defm export: Eq<"export">,
106 HelpText<"Force a symbol to be exported">;
118defm export: Eq<"export", "Force a symbol to be exported">;
107119
108120def export_all: F<"export-all">,
109121 HelpText<"Export all symbols (normally combined with --no-gc-sections)">;
......@@ -117,6 +129,9 @@ def global_base: J<"global-base=">,
117129def import_memory: F<"import-memory">,
118130 HelpText<"Import memory from the environment">;
119131
132def shared_memory: F<"shared-memory">,
133 HelpText<"Use shared linear memory">;
134
120135def import_table: F<"import-table">,
121136 HelpText<"Import function table from the environment">;
122137
......@@ -137,12 +152,15 @@ defm whole_archive: B<"whole-archive",
137152 "Do not force load of all members in a static library (default)">;
138153
139154// Aliases
140def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
141def alias_entry_entry: J<"entry=">, Alias<entry>;
142def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>;
143def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>;
144def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;
145def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
155def: JoinedOrSeparate<["-"], "e">, Alias<entry>;
156def: J<"entry=">, Alias<entry>;
157def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">;
158def: Flag<["-"], "i">, Alias<initial_memory>;
159def: Flag<["-"], "m">, Alias<max_memory>;
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
147165// LTO-related options.
148166def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
......@@ -153,6 +171,5 @@ def disable_verify: F<"disable-verify">;
153171def save_temps: F<"save-temps">;
154172def thinlto_cache_dir: J<"thinlto-cache-dir=">,
155173 HelpText<"Path to ThinLTO cached object file directory">;
156defm thinlto_cache_policy: Eq<"thinlto-cache-policy">,
157 HelpText<"Pruning policy for the ThinLTO cache">;
174defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">;
158175def 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) {
4040 return "MEMORY";
4141 case WASM_SEC_GLOBAL:
4242 return "GLOBAL";
43 case WASM_SEC_EVENT:
44 return "EVENT";
4345 case WASM_SEC_EXPORT:
4446 return "EXPORT";
4547 case WASM_SEC_START:
......@@ -136,9 +138,17 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments)
136138 for (OutputSegment *Segment : Segments) {
137139 raw_string_ostream OS(Segment->Header);
138140 writeUleb128(OS, 0, "memory index");
139 writeUleb128(OS, WASM_OPCODE_I32_CONST, "opcode:i32const");
140 writeSleb128(OS, Segment->StartVA, "memory offset");
141 writeUleb128(OS, WASM_OPCODE_END, "opcode:end");
141 WasmInitExpr InitExpr;
142 if (Config->Pic) {
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);
142152 writeUleb128(OS, Segment->Size, "segment size");
143153 OS.flush();
144154
deps/lld/wasm/OutputSections.h+3-5
......@@ -13,11 +13,9 @@
1313#include "InputChunks.h"
1414#include "WriterUtils.h"
1515#include "lld/Common/ErrorHandler.h"
16#include "lld/Common/LLVM.h"
1617#include "llvm/ADT/DenseMap.h"
1718
18using llvm::raw_ostream;
19using llvm::raw_string_ostream;
20
2119namespace lld {
2220
2321namespace wasm {
......@@ -82,7 +80,7 @@ public:
8280 std::string Body;
8381
8482protected:
85 raw_string_ostream BodyOutputStream;
83 llvm::raw_string_ostream BodyOutputStream;
8684};
8785
8886class CodeSection : public OutputSection {
......@@ -113,7 +111,7 @@ protected:
113111 size_t BodySize = 0;
114112};
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
117115// used for storing user-defined metadata. Unlike the core sections types
118116// they are identified by their string name.
119117// The linker combines custom sections that have the same name by simply
deps/lld/wasm/OutputSegment.h+1-1
......@@ -26,7 +26,7 @@ public:
2626 void addInputSegment(InputSegment *InSeg) {
2727 Alignment = std::max(Alignment, InSeg->getAlignment());
2828 InputSegments.push_back(InSeg);
29 Size = llvm::alignTo(Size, InSeg->getAlignment());
29 Size = llvm::alignTo(Size, 1 << InSeg->getAlignment());
3030 InSeg->OutputSeg = this;
3131 InSeg->OutputSegmentOffset = Size;
3232 Size += InSeg->getSize();
deps/lld/wasm/SymbolTable.cpp+88-59
......@@ -10,6 +10,7 @@
1010#include "SymbolTable.h"
1111#include "Config.h"
1212#include "InputChunks.h"
13#include "InputEvent.h"
1314#include "InputGlobal.h"
1415#include "WriterUtils.h"
1516#include "lld/Common/ErrorHandler.h"
......@@ -20,6 +21,7 @@
2021
2122using namespace llvm;
2223using namespace llvm::wasm;
24using namespace llvm::object;
2325using namespace lld;
2426using namespace lld::wasm;
2527
......@@ -60,7 +62,6 @@ void SymbolTable::addCombinedLTOObject() {
6062}
6163
6264void SymbolTable::reportRemainingUndefines() {
63 SetVector<Symbol *> Undefs;
6465 for (Symbol *Sym : SymVector) {
6566 if (!Sym->isUndefined() || Sym->isWeak())
6667 continue;
......@@ -68,34 +69,26 @@ void SymbolTable::reportRemainingUndefines() {
6869 continue;
6970 if (!Sym->IsUsedInRegularObj)
7071 continue;
71 Undefs.insert(Sym);
72 error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
7273 }
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));
8574}
8675
8776Symbol *SymbolTable::find(StringRef Name) {
8877 return SymMap.lookup(CachedHashStringRef(Name));
8978}
9079
91std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
80std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
81 bool Inserted = false;
9282 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
93 if (Sym)
94 return {Sym, false};
95 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
96 Sym->IsUsedInRegularObj = false;
97 SymVector.emplace_back(Sym);
98 return {Sym, true};
83 if (!Sym) {
84 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
85 Sym->IsUsedInRegularObj = false;
86 SymVector.emplace_back(Sym);
87 Inserted = true;
88 }
89 if (!File || File->kind() == InputFile::ObjectKind)
90 Sym->IsUsedInRegularObj = true;
91 return {Sym, Inserted};
9992}
10093
10194static void reportTypeError(const Symbol *Existing, const InputFile *File,
......@@ -106,6 +99,8 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,
10699 " in " + toString(File));
107100}
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.
109104static void checkFunctionType(Symbol *Existing, const InputFile *File,
110105 const WasmSignature *NewSig) {
111106 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
......@@ -117,9 +112,9 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,
117112 if (!NewSig)
118113 return;
119114
120 const WasmSignature *OldSig = ExistingFunction->FunctionType;
115 const WasmSignature *OldSig = ExistingFunction->Signature;
121116 if (!OldSig) {
122 ExistingFunction->FunctionType = NewSig;
117 ExistingFunction->Signature = NewSig;
123118 return;
124119 }
125120
......@@ -130,8 +125,6 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,
130125 toString(*NewSig) + " in " + toString(File));
131126}
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.
135128static void checkGlobalType(const Symbol *Existing, const InputFile *File,
136129 const WasmGlobalType *NewType) {
137130 if (!isa<GlobalSymbol>(Existing)) {
......@@ -147,6 +140,28 @@ static void checkGlobalType(const Symbol *Existing, const InputFile *File,
147140 }
148141}
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
150165static void checkDataType(const Symbol *Existing, const InputFile *File) {
151166 if (!isa<DataSymbol>(Existing))
152167 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
......@@ -158,15 +173,15 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
158173 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
159174 assert(!find(Name));
160175 SyntheticFunctions.emplace_back(Function);
161 return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags,
162 nullptr, Function);
176 return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name,
177 Flags, nullptr, Function);
163178}
164179
165180DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
166181 uint32_t Flags) {
167182 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
168183 assert(!find(Name));
169 return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags);
184 return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);
170185}
171186
172187DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
......@@ -175,8 +190,8 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
175190 << "\n");
176191 assert(!find(Name));
177192 SyntheticGlobals.emplace_back(Global);
178 return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr,
179 Global);
193 return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags,
194 nullptr, Global);
180195}
181196
182197static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
......@@ -210,13 +225,12 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
210225Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
211226 InputFile *File,
212227 InputFunction *Function) {
213 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");
228 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
229 << (Function ? toString(Function->Signature) : "none")
230 << "]\n");
214231 Symbol *S;
215232 bool WasInserted;
216 std::tie(S, WasInserted) = insert(Name);
217
218 if (!File || File->kind() == InputFile::ObjectKind)
219 S->IsUsedInRegularObj = true;
233 std::tie(S, WasInserted) = insert(Name, File);
220234
221235 if (WasInserted || S->isLazy()) {
222236 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
......@@ -226,8 +240,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
226240 if (Function)
227241 checkFunctionType(S, File, &Function->Signature);
228242
229 if (shouldReplace(S, File, Flags))
230 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
243 if (shouldReplace(S, File, Flags)) {
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 }
231253 return S;
232254}
233255
......@@ -238,10 +260,7 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
238260 << "\n");
239261 Symbol *S;
240262 bool WasInserted;
241 std::tie(S, WasInserted) = insert(Name);
242
243 if (!File || File->kind() == InputFile::ObjectKind)
244 S->IsUsedInRegularObj = true;
263 std::tie(S, WasInserted) = insert(Name, File);
245264
246265 if (WasInserted || S->isLazy()) {
247266 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
......@@ -258,12 +277,10 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
258277Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
259278 InputFile *File, InputGlobal *Global) {
260279 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
280
261281 Symbol *S;
262282 bool WasInserted;
263 std::tie(S, WasInserted) = insert(Name);
264
265 if (!File || File->kind() == InputFile::ObjectKind)
266 S->IsUsedInRegularObj = true;
283 std::tie(S, WasInserted) = insert(Name, File);
267284
268285 if (WasInserted || S->isLazy()) {
269286 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
......@@ -277,17 +294,35 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
277294 return S;
278295}
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
280317Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
281318 InputFile *File,
282319 const WasmSignature *Sig) {
283 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
320 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
321 " [" << (Sig ? toString(*Sig) : "none") << "]\n");
284322
285323 Symbol *S;
286324 bool WasInserted;
287 std::tie(S, WasInserted) = insert(Name);
288
289 if (!File || File->kind() == InputFile::ObjectKind)
290 S->IsUsedInRegularObj = true;
325 std::tie(S, WasInserted) = insert(Name, File);
291326
292327 if (WasInserted)
293328 replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
......@@ -305,10 +340,7 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
305340
306341 Symbol *S;
307342 bool WasInserted;
308 std::tie(S, WasInserted) = insert(Name);
309
310 if (!File || File->kind() == InputFile::ObjectKind)
311 S->IsUsedInRegularObj = true;
343 std::tie(S, WasInserted) = insert(Name, File);
312344
313345 if (WasInserted)
314346 replaceSymbol<UndefinedData>(S, Name, Flags, File);
......@@ -326,10 +358,7 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
326358
327359 Symbol *S;
328360 bool WasInserted;
329 std::tie(S, WasInserted) = insert(Name);
330
331 if (!File || File->kind() == InputFile::ObjectKind)
332 S->IsUsedInRegularObj = true;
361 std::tie(S, WasInserted) = insert(Name, File);
333362
334363 if (WasInserted)
335364 replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
......@@ -346,7 +375,7 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
346375
347376 Symbol *S;
348377 bool WasInserted;
349 std::tie(S, WasInserted) = insert(Name);
378 std::tie(S, WasInserted) = insert(Name, nullptr);
350379
351380 if (WasInserted) {
352381 replaceSymbol<LazySymbol>(S, Name, File, *Sym);
deps/lld/wasm/SymbolTable.h+5-6
......@@ -13,12 +13,9 @@
1313#include "InputFiles.h"
1414#include "LTO.h"
1515#include "Symbols.h"
16#include "lld/Common/LLVM.h"
1617#include "llvm/ADT/CachedHashString.h"
1718#include "llvm/ADT/DenseSet.h"
18#include "llvm/Support/raw_ostream.h"
19
20using llvm::wasm::WasmGlobalType;
21using llvm::wasm::WasmSignature;
2219
2320namespace lld {
2421namespace wasm {
......@@ -59,6 +56,8 @@ public:
5956 uint32_t Size);
6057 Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
6158 InputGlobal *G);
59 Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
60 InputEvent *E);
6261
6362 Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
6463 const WasmSignature *Signature);
......@@ -66,7 +65,7 @@ public:
6665 Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
6766 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
7170 bool addComdat(StringRef Name);
7271
......@@ -77,7 +76,7 @@ public:
7776 InputFunction *Function);
7877
7978private:
80 std::pair<Symbol *, bool> insert(StringRef Name);
79 std::pair<Symbol *, bool> insert(StringRef Name, InputFile *File);
8180
8281 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
8382 std::vector<Symbol *> SymVector;
deps/lld/wasm/Symbols.cpp+48-4
......@@ -10,6 +10,7 @@
1010#include "Symbols.h"
1111#include "Config.h"
1212#include "InputChunks.h"
13#include "InputEvent.h"
1314#include "InputFiles.h"
1415#include "InputGlobal.h"
1516#include "OutputSegment.h"
......@@ -27,7 +28,9 @@ DefinedFunction *WasmSym::CallCtors;
2728DefinedData *WasmSym::DsoHandle;
2829DefinedData *WasmSym::DataEnd;
2930DefinedData *WasmSym::HeapBase;
30DefinedGlobal *WasmSym::StackPointer;
31GlobalSymbol *WasmSym::StackPointer;
32UndefinedGlobal *WasmSym::TableBase;
33UndefinedGlobal *WasmSym::MemoryBase;
3134
3235WasmSymbolType Symbol::getWasmType() const {
3336 if (isa<FunctionSymbol>(this))
......@@ -36,6 +39,8 @@ WasmSymbolType Symbol::getWasmType() const {
3639 return WASM_SYMBOL_TYPE_DATA;
3740 if (isa<GlobalSymbol>(this))
3841 return WASM_SYMBOL_TYPE_GLOBAL;
42 if (isa<EventSymbol>(this))
43 return WASM_SYMBOL_TYPE_EVENT;
3944 if (isa<SectionSymbol>(this))
4045 return WASM_SYMBOL_TYPE_SECTION;
4146 llvm_unreachable("invalid symbol kind");
......@@ -52,6 +57,8 @@ InputChunk *Symbol::getChunk() const {
5257bool Symbol::isLive() const {
5358 if (auto *G = dyn_cast<DefinedGlobal>(this))
5459 return G->Global->Live;
60 if (auto *E = dyn_cast<DefinedEvent>(this))
61 return E->Event->Live;
5562 if (InputChunk *C = getChunk())
5663 return C->Live;
5764 return Referenced;
......@@ -60,6 +67,8 @@ bool Symbol::isLive() const {
6067void Symbol::markLive() {
6168 if (auto *G = dyn_cast<DefinedGlobal>(this))
6269 G->Global->Live = true;
70 if (auto *E = dyn_cast<DefinedEvent>(this))
71 E->Event->Live = true;
6372 if (InputChunk *C = getChunk())
6473 C->Live = true;
6574 Referenced = true;
......@@ -105,7 +114,10 @@ bool Symbol::isExported() const {
105114 if (ForceExport || Config->ExportAll)
106115 return true;
107116
108 return !isHidden();
117 if (Config->ExportDynamic && !isHidden())
118 return true;
119
120 return false;
109121}
110122
111123uint32_t FunctionSymbol::getFunctionIndex() const {
......@@ -207,6 +219,32 @@ DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
207219 Global ? &Global->getType() : nullptr),
208220 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
210248uint32_t SectionSymbol::getOutputSectionIndex() const {
211249 LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
212250 assert(OutputSectionIndex != INVALID_INDEX);
......@@ -223,10 +261,14 @@ void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
223261void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
224262
225263std::string lld::toString(const wasm::Symbol &Sym) {
264 return lld::maybeDemangleSymbol(Sym.getName());
265}
266
267std::string lld::maybeDemangleSymbol(StringRef Name) {
226268 if (Config->Demangle)
227 if (Optional<std::string> S = demangleItanium(Sym.getName()))
269 if (Optional<std::string> S = demangleItanium(Name))
228270 return *S;
229 return Sym.getName();
271 return Name;
230272}
231273
232274std::string lld::toString(wasm::Symbol::Kind Kind) {
......@@ -237,6 +279,8 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {
237279 return "DefinedData";
238280 case wasm::Symbol::DefinedGlobalKind:
239281 return "DefinedGlobal";
282 case wasm::Symbol::DefinedEventKind:
283 return "DefinedEvent";
240284 case wasm::Symbol::UndefinedFunctionKind:
241285 return "UndefinedFunction";
242286 case wasm::Symbol::UndefinedDataKind:
deps/lld/wasm/Symbols.h+72-21
......@@ -15,21 +15,17 @@
1515#include "llvm/Object/Archive.h"
1616#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
2518namespace lld {
2619namespace wasm {
2720
21using llvm::wasm::WasmSymbolType;
22
2823class InputFile;
2924class InputChunk;
3025class InputSegment;
3126class InputFunction;
3227class InputGlobal;
28class InputEvent;
3329class InputSection;
3430
3531#define INVALID_INDEX UINT32_MAX
......@@ -41,6 +37,7 @@ public:
4137 DefinedFunctionKind,
4238 DefinedDataKind,
4339 DefinedGlobalKind,
40 DefinedEventKind,
4441 SectionKind,
4542 UndefinedFunctionKind,
4643 UndefinedDataKind,
......@@ -52,7 +49,8 @@ public:
5249
5350 bool isDefined() const {
5451 return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind ||
55 SymbolKind == DefinedGlobalKind || SymbolKind == SectionKind;
52 SymbolKind == DefinedGlobalKind || SymbolKind == DefinedEventKind ||
53 SymbolKind == SectionKind;
5654 }
5755
5856 bool isUndefined() const {
......@@ -126,12 +124,12 @@ public:
126124 void setFunctionIndex(uint32_t Index);
127125 bool hasFunctionIndex() const;
128126
129 const WasmSignature *FunctionType;
127 const WasmSignature *Signature;
130128
131129protected:
132130 FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
133 const WasmSignature *Type)
134 : Symbol(Name, K, Flags, F), FunctionType(Type) {}
131 const WasmSignature *Sig)
132 : Symbol(Name, K, Flags, F), Signature(Sig) {}
135133
136134 uint32_t TableIndex = INVALID_INDEX;
137135 uint32_t FunctionIndex = INVALID_INDEX;
......@@ -245,8 +243,6 @@ protected:
245243 const WasmGlobalType *GlobalType)
246244 : 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.
250246 const WasmGlobalType *GlobalType;
251247 uint32_t GlobalIndex = INVALID_INDEX;
252248};
......@@ -274,16 +270,61 @@ public:
274270 }
275271};
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
277317class LazySymbol : public Symbol {
278318public:
279 LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym)
319 LazySymbol(StringRef Name, InputFile *File,
320 const llvm::object::Archive::Symbol &Sym)
280321 : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
281322
282323 static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
283324 void fetch();
284325
285326private:
286 Archive::Symbol ArchiveSymbol;
327 llvm::object::Archive::Symbol ArchiveSymbol;
287328};
288329
289330// linker-generated symbols
......@@ -291,7 +332,7 @@ struct WasmSym {
291332 // __stack_pointer
292333 // Global that holds the address of the top of the explicit value stack in
293334 // linear memory.
294 static DefinedGlobal *StackPointer;
335 static GlobalSymbol *StackPointer;
295336
296337 // __data_end
297338 // Symbol marking the end of the data and bss.
......@@ -310,6 +351,14 @@ struct WasmSym {
310351 // __dso_handle
311352 // Symbol used in calls to __cxa_atexit to determine current DLL
312353 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;
313362};
314363
315364// A buffer class that is large enough to hold any Symbol-derived
......@@ -319,10 +368,11 @@ union SymbolUnion {
319368 alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
320369 alignas(DefinedData) char B[sizeof(DefinedData)];
321370 alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
322 alignas(LazySymbol) char D[sizeof(LazySymbol)];
323 alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)];
324 alignas(UndefinedData) char F[sizeof(UndefinedData)];
325 alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)];
371 alignas(DefinedEvent) char D[sizeof(DefinedEvent)];
372 alignas(LazySymbol) char E[sizeof(LazySymbol)];
373 alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)];
374 alignas(UndefinedData) char G[sizeof(UndefinedData)];
375 alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)];
326376 alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
327377};
328378
......@@ -330,7 +380,7 @@ template <typename T, typename... ArgT>
330380T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331381 static_assert(std::is_trivially_destructible<T>(),
332382 "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");
334384 static_assert(alignof(T) <= alignof(SymbolUnion),
335385 "SymbolUnion not aligned enough");
336386 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
......@@ -349,6 +399,7 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
349399// Returns a symbol name for an error message.
350400std::string toString(const wasm::Symbol &Sym);
351401std::string toString(wasm::Symbol::Kind Kind);
402std::string maybeDemangleSymbol(StringRef Name);
352403
353404} // namespace lld
354405
deps/lld/wasm/Writer.cpp+155-35
......@@ -10,6 +10,7 @@
1010#include "Writer.h"
1111#include "Config.h"
1212#include "InputChunks.h"
13#include "InputEvent.h"
1314#include "InputGlobal.h"
1415#include "OutputSections.h"
1516#include "OutputSegment.h"
......@@ -39,7 +40,6 @@ using namespace lld;
3940using namespace lld::wasm;
4041
4142static constexpr int kStackAlignment = 16;
42static constexpr int kInitialTableOffset = 1;
4343static constexpr const char *kFunctionTableName = "__indirect_function_table";
4444
4545namespace {
......@@ -81,6 +81,7 @@ private:
8181 void createFunctionSection();
8282 void createTableSection();
8383 void createGlobalSection();
84 void createEventSection();
8485 void createExportSection();
8586 void createImportSection();
8687 void createMemorySection();
......@@ -90,6 +91,7 @@ private:
9091 void createCustomSections();
9192
9293 // Custom sections
94 void createDylinkSection();
9395 void createRelocSections();
9496 void createLinkingSection();
9597 void createNameSection();
......@@ -98,18 +100,25 @@ private:
98100 void writeSections();
99101
100102 uint64_t FileSize = 0;
103 uint32_t TableBase = 0;
101104 uint32_t NumMemoryPages = 0;
102105 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
104111 std::vector<const WasmSignature *> Types;
105112 DenseMap<WasmSignature, int32_t> TypeIndices;
106113 std::vector<const Symbol *> ImportedSymbols;
107114 unsigned NumImportedFunctions = 0;
108115 unsigned NumImportedGlobals = 0;
116 unsigned NumImportedEvents = 0;
109117 std::vector<WasmExport> Exports;
110118 std::vector<const DefinedData *> DefinedFakeGlobals;
111119 std::vector<InputGlobal *> InputGlobals;
112120 std::vector<InputFunction *> InputFunctions;
121 std::vector<InputEvent *> InputEvents;
113122 std::vector<const FunctionSymbol *> IndirectFunctions;
114123 std::vector<const Symbol *> SymtabEntries;
115124 std::vector<WasmInitEntry> InitFunctions;
......@@ -155,17 +164,19 @@ void Writer::createImportSection() {
155164 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
156165 Import.Memory.Maximum = MaxMemoryPages;
157166 }
167 if (Config->SharedMemory)
168 Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
158169 writeImport(OS, Import);
159170 }
160171
161172 if (Config->ImportTable) {
162 uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();
173 uint32_t TableSize = TableBase + IndirectFunctions.size();
163174 WasmImport Import;
164175 Import.Module = "env";
165176 Import.Field = kFunctionTableName;
166177 Import.Kind = WASM_EXTERNAL_TABLE;
167 Import.Table.ElemType = WASM_TYPE_ANYFUNC;
168 Import.Table.Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
178 Import.Table.ElemType = WASM_TYPE_FUNCREF;
179 Import.Table.Limits = {0, TableSize, 0};
169180 writeImport(OS, Import);
170181 }
171182
......@@ -175,11 +186,15 @@ void Writer::createImportSection() {
175186 Import.Field = Sym->getName();
176187 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
177188 Import.Kind = WASM_EXTERNAL_FUNCTION;
178 Import.SigIndex = lookupType(*FunctionSym->FunctionType);
179 } else {
180 auto *GlobalSym = cast<GlobalSymbol>(Sym);
189 Import.SigIndex = lookupType(*FunctionSym->Signature);
190 } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
181191 Import.Kind = WASM_EXTERNAL_GLOBAL;
182192 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);
183198 }
184199 writeImport(OS, Import);
185200 }
......@@ -214,8 +229,12 @@ void Writer::createMemorySection() {
214229
215230 bool HasMax = MaxMemoryPages != 0;
216231 writeUleb128(OS, 1, "memory count");
217 writeUleb128(OS, HasMax ? static_cast<unsigned>(WASM_LIMITS_FLAG_HAS_MAX) : 0,
218 "memory limits flags");
232 unsigned Flags = 0;
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");
219238 writeUleb128(OS, NumMemoryPages, "initial pages");
220239 if (HasMax)
221240 writeUleb128(OS, MaxMemoryPages, "max pages");
......@@ -241,6 +260,31 @@ void Writer::createGlobalSection() {
241260 }
242261}
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
244288void Writer::createTableSection() {
245289 if (Config->ImportTable)
246290 return;
......@@ -253,14 +297,14 @@ void Writer::createTableSection() {
253297 // no address-taken function will fail at validation time since it is
254298 // a validation error to include a call_indirect instruction if there
255299 // is not table.
256 uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();
300 uint32_t TableSize = TableBase + IndirectFunctions.size();
257301
258302 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
259303 raw_ostream &OS = Section->getStream();
260304
261305 writeUleb128(OS, 1, "table count");
262306 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});
264308}
265309
266310void Writer::createExportSection() {
......@@ -319,12 +363,17 @@ void Writer::createElemSection() {
319363 writeUleb128(OS, 1, "segment count");
320364 writeUleb128(OS, 0, "table index");
321365 WasmInitExpr InitExpr;
322 InitExpr.Opcode = WASM_OPCODE_I32_CONST;
323 InitExpr.Value.Int32 = kInitialTableOffset;
366 if (Config->Pic) {
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 }
324373 writeInitExpr(OS, InitExpr);
325374 writeUleb128(OS, IndirectFunctions.size(), "elem count");
326375
327 uint32_t TableIndex = kInitialTableOffset;
376 uint32_t TableIndex = TableBase;
328377 for (const FunctionSymbol *Sym : IndirectFunctions) {
329378 assert(Sym->getTableIndex() == TableIndex);
330379 writeUleb128(OS, Sym->getFunctionIndex(), "function index");
......@@ -419,6 +468,21 @@ public:
419468 raw_string_ostream OS{Body};
420469};
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
422486// Create the custom "linking" section containing linker metadata.
423487// This is only created when relocatable output is requested.
424488void Writer::createLinkingSection() {
......@@ -448,6 +512,10 @@ void Writer::createLinkingSection() {
448512 writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
449513 if (Sym->isDefined())
450514 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");
451519 } else if (isa<DataSymbol>(Sym)) {
452520 writeStr(Sub.OS, Sym->getName(), "sym name");
453521 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
......@@ -548,8 +616,7 @@ void Writer::createNameSection() {
548616 for (const Symbol *S : ImportedSymbols) {
549617 if (auto *F = dyn_cast<FunctionSymbol>(S)) {
550618 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
551 Optional<std::string> Name = demangleItanium(F->getName());
552 writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
619 writeStr(Sub.OS, toString(*S), "symbol name");
553620 }
554621 }
555622 for (const InputFunction *F : InputFunctions) {
......@@ -558,8 +625,7 @@ void Writer::createNameSection() {
558625 if (!F->getDebugName().empty()) {
559626 writeStr(Sub.OS, F->getDebugName(), "symbol name");
560627 } else {
561 Optional<std::string> Name = demangleItanium(F->getName());
562 writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
628 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name");
563629 }
564630 }
565631 }
......@@ -586,16 +652,16 @@ void Writer::writeSections() {
586652// - heap start / unallocated
587653//
588654// 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 rather
590// than overwriting global data, but also increases code size since all static
591// data loads and stores requires larger offsets.
655// This can be useful since it means that stack overflow traps immediately
656// rather than overwriting global data, but also increases code size since all
657// static data loads and stores requires larger offsets.
592658void Writer::layoutMemory() {
593659 createOutputSegments();
594660
595661 uint32_t MemoryPtr = 0;
596662
597663 auto PlaceStack = [&]() {
598 if (Config->Relocatable)
664 if (Config->Relocatable || Config->Shared)
599665 return;
600666 MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
601667 if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
......@@ -603,7 +669,8 @@ void Writer::layoutMemory() {
603669 log("mem: stack size = " + Twine(Config->ZStackSize));
604670 log("mem: stack base = " + Twine(MemoryPtr));
605671 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;
607674 log("mem: stack top = " + Twine(MemoryPtr));
608675 };
609676
......@@ -621,8 +688,10 @@ void Writer::layoutMemory() {
621688 if (WasmSym::DsoHandle)
622689 WasmSym::DsoHandle->setVirtualAddress(DataStart);
623690
691 MemAlign = 0;
624692 for (OutputSegment *Seg : Segments) {
625 MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
693 MemAlign = std::max(MemAlign, Seg->Alignment);
694 MemoryPtr = alignTo(MemoryPtr, 1 << Seg->Alignment);
626695 Seg->StartVA = MemoryPtr;
627696 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
628697 MemoryPtr, Seg->Size, Seg->Alignment));
......@@ -635,6 +704,11 @@ void Writer::layoutMemory() {
635704
636705 log("mem: static data = " + Twine(MemoryPtr - DataStart));
637706
707 if (Config->Shared) {
708 MemSize = MemoryPtr;
709 return;
710 }
711
638712 if (!Config->StackFirst)
639713 PlaceStack();
640714
......@@ -654,8 +728,8 @@ void Writer::layoutMemory() {
654728 else
655729 MemoryPtr = Config->InitialMemory;
656730 }
657 uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize);
658 NumMemoryPages = MemSize / WasmPageSize;
731 MemSize = MemoryPtr;
732 NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
659733 log("mem: total pages = " + Twine(NumMemoryPages));
660734
661735 if (Config->MaxMemory != 0) {
......@@ -678,12 +752,15 @@ SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
678752
679753void Writer::createSections() {
680754 // Known sections
755 if (Config->Pic)
756 createDylinkSection();
681757 createTypeSection();
682758 createImportSection();
683759 createFunctionSection();
684760 createTableSection();
685761 createMemorySection();
686762 createGlobalSection();
763 createEventSection();
687764 createExportSection();
688765 createElemSection();
689766 createCodeSection();
......@@ -722,8 +799,10 @@ void Writer::calculateImports() {
722799 ImportedSymbols.emplace_back(Sym);
723800 if (auto *F = dyn_cast<FunctionSymbol>(Sym))
724801 F->setFunctionIndex(NumImportedFunctions++);
802 else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
803 G->setGlobalIndex(NumImportedGlobals++);
725804 else
726 cast<GlobalSymbol>(Sym)->setGlobalIndex(NumImportedGlobals++);
805 cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
727806 }
728807}
729808
......@@ -759,6 +838,8 @@ void Writer::calculateExports() {
759838 continue;
760839 }
761840 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
841 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
842 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
762843 } else {
763844 auto *D = cast<DefinedData>(Sym);
764845 DefinedFakeGlobals.emplace_back(D);
......@@ -836,6 +917,8 @@ void Writer::calculateTypes() {
836917 // 1. Any signature used in the TYPE relocation
837918 // 2. The signatures of all imported functions
838919 // 3. The signatures of all defined functions
920 // 4. The signatures of all imported events
921 // 5. The signatures of all defined events
839922
840923 for (ObjFile *File : Symtab->ObjectFiles) {
841924 ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
......@@ -844,16 +927,23 @@ void Writer::calculateTypes() {
844927 File->TypeMap[I] = registerType(Types[I]);
845928 }
846929
847 for (const Symbol *Sym : ImportedSymbols)
930 for (const Symbol *Sym : ImportedSymbols) {
848931 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
851937 for (const InputFunction *F : InputFunctions)
852938 registerType(F->Signature);
939
940 for (const InputEvent *E : InputEvents)
941 registerType(E->Signature);
853942}
854943
855944void Writer::assignIndexes() {
856 uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
945 assert(InputFunctions.empty());
946 uint32_t FunctionIndex = NumImportedFunctions;
857947 auto AddDefinedFunction = [&](InputFunction *Func) {
858948 if (!Func->Live)
859949 return;
......@@ -870,7 +960,7 @@ void Writer::assignIndexes() {
870960 AddDefinedFunction(Func);
871961 }
872962
873 uint32_t TableIndex = kInitialTableOffset;
963 uint32_t TableIndex = TableBase;
874964 auto HandleRelocs = [&](InputChunk *Chunk) {
875965 if (!Chunk->Live)
876966 return;
......@@ -902,7 +992,8 @@ void Writer::assignIndexes() {
902992 HandleRelocs(P);
903993 }
904994
905 uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();
995 assert(InputGlobals.empty());
996 uint32_t GlobalIndex = NumImportedGlobals;
906997 auto AddDefinedGlobal = [&](InputGlobal *Global) {
907998 if (Global->Live) {
908999 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
......@@ -919,9 +1010,29 @@ void Writer::assignIndexes() {
9191010 for (InputGlobal *Global : File->Globals)
9201011 AddDefinedGlobal(Global);
9211012 }
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 }
9221029}
9231030
9241031static 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";
9251036 if (!Config->MergeDataSegments)
9261037 return Name;
9271038 if (Name.startswith(".text."))
......@@ -930,6 +1041,8 @@ static StringRef getOutputDataSegmentName(StringRef Name) {
9301041 return ".data";
9311042 if (Name.startswith(".bss."))
9321043 return ".bss";
1044 if (Name.startswith(".rodata."))
1045 return ".rodata";
9331046 return Name;
9341047}
9351048
......@@ -977,7 +1090,7 @@ void Writer::createCtorFunction() {
9771090 OS << BodyContent;
9781091 }
9791092
980 ArrayRef<uint8_t> Body = toArrayRef(Saver.save(FunctionBody));
1093 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
9811094 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
9821095}
9831096
......@@ -989,7 +1102,7 @@ void Writer::calculateInitFunctions() {
9891102 const WasmLinkingData &L = File->getWasmObj()->linkingData();
9901103 for (const WasmInitFunc &F : L.InitFunctions) {
9911104 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
992 if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT})
1105 if (*Sym->Signature != WasmSignature{{}, {}})
9931106 error("invalid signature for init func: " + toString(*Sym));
9941107 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
9951108 }
......@@ -1004,9 +1117,14 @@ void Writer::calculateInitFunctions() {
10041117}
10051118
10061119void Writer::run() {
1007 if (Config->Relocatable)
1120 if (Config->Relocatable || Config->Pic)
10081121 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
10101128 log("-- calculateImports");
10111129 calculateImports();
10121130 log("-- assignIndexes");
......@@ -1029,8 +1147,10 @@ void Writer::run() {
10291147 if (errorHandler().Verbose) {
10301148 log("Defined Functions: " + Twine(InputFunctions.size()));
10311149 log("Defined Globals : " + Twine(InputGlobals.size()));
1150 log("Defined Events : " + Twine(InputEvents.size()));
10321151 log("Function Imports : " + Twine(NumImportedFunctions));
10331152 log("Global Imports : " + Twine(NumImportedGlobals));
1153 log("Event Imports : " + Twine(NumImportedEvents));
10341154 for (ObjFile *File : Symtab->ObjectFiles)
10351155 File->dumpInfo();
10361156 }
deps/lld/wasm/WriterUtils.cpp+43-39
......@@ -17,22 +17,6 @@
1717
1818using namespace llvm;
1919using 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
3721namespace lld {
3822
......@@ -73,21 +57,20 @@ void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
7357 support::endian::write(OS, Number, support::little);
7458}
7559
76void wasm::writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg) {
77 writeU8(OS, Type, Msg + "[type: " + valueTypeToString(Type) + "]");
60void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
61 writeU8(OS, static_cast<uint8_t>(Type),
62 Msg + "[type: " + toString(Type) + "]");
7863}
7964
8065void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
8166 writeU8(OS, WASM_TYPE_FUNC, "signature type");
82 writeUleb128(OS, Sig.ParamTypes.size(), "param Count");
83 for (uint8_t ParamType : Sig.ParamTypes) {
67 writeUleb128(OS, Sig.Params.size(), "param Count");
68 for (ValType ParamType : Sig.Params) {
8469 writeValueType(OS, ParamType, "param type");
8570 }
86 if (Sig.ReturnType == WASM_TYPE_NORESULT) {
87 writeUleb128(OS, 0, "result Count");
88 } else {
89 writeUleb128(OS, 1, "result Count");
90 writeValueType(OS, Sig.ReturnType, "result type");
71 writeUleb128(OS, Sig.Returns.size(), "result Count");
72 if (Sig.Returns.size()) {
73 writeValueType(OS, Sig.Returns[0], "result type");
9174 }
9275}
9376
......@@ -100,7 +83,7 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
10083 case WASM_OPCODE_I64_CONST:
10184 writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
10285 break;
103 case WASM_OPCODE_GET_GLOBAL:
86 case WASM_OPCODE_GLOBAL_GET:
10487 writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
10588 break;
10689 default:
......@@ -117,7 +100,8 @@ void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
117100}
118101
119102void 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");
121105 writeU8(OS, Type.Mutable, "global mutable");
122106}
123107
......@@ -126,8 +110,17 @@ void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
126110 writeInitExpr(OS, Global.InitExpr);
127111}
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
129122void 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");
131124 writeLimits(OS, Type.Limits);
132125}
133126
......@@ -142,6 +135,9 @@ void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
142135 case WASM_EXTERNAL_GLOBAL:
143136 writeGlobalType(OS, Import.Global);
144137 break;
138 case WASM_EXTERNAL_EVENT:
139 writeEventType(OS, Import.Event);
140 break;
145141 case WASM_EXTERNAL_MEMORY:
146142 writeLimits(OS, Import.Memory);
147143 break;
......@@ -178,13 +174,15 @@ void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
178174std::string lld::toString(ValType Type) {
179175 switch (Type) {
180176 case ValType::I32:
181 return "I32";
177 return "i32";
182178 case ValType::I64:
183 return "I64";
179 return "i64";
184180 case ValType::F32:
185 return "F32";
181 return "f32";
186182 case ValType::F64:
187 return "F64";
183 return "f64";
184 case ValType::V128:
185 return "v128";
188186 case ValType::EXCEPT_REF:
189187 return "except_ref";
190188 }
......@@ -193,20 +191,26 @@ std::string lld::toString(ValType Type) {
193191
194192std::string lld::toString(const WasmSignature &Sig) {
195193 SmallString<128> S("(");
196 for (uint32_t Type : Sig.ParamTypes) {
194 for (ValType Type : Sig.Params) {
197195 if (S.size() != 1)
198196 S += ", ";
199 S += toString(static_cast<ValType>(Type));
197 S += toString(Type);
200198 }
201199 S += ") -> ";
202 if (Sig.ReturnType == WASM_TYPE_NORESULT)
200 if (Sig.Returns.size() == 0)
203201 S += "void";
204202 else
205 S += toString(static_cast<ValType>(Sig.ReturnType));
203 S += toString(Sig.Returns[0]);
206204 return S.str();
207205}
208206
209std::string lld::toString(const WasmGlobalType &Sig) {
210 return (Sig.Mutable ? "var " : "const ") +
211 toString(static_cast<ValType>(Sig.Type));
207std::string lld::toString(const WasmGlobalType &Type) {
208 return (Type.Mutable ? "var " : "const ") +
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";
212216}
deps/lld/wasm/WriterUtils.h+8-5
......@@ -13,9 +13,6 @@
1313#include "lld/Common/LLVM.h"
1414#include "llvm/ADT/Twine.h"
1515#include "llvm/Object/Wasm.h"
16#include "llvm/Support/raw_ostream.h"
17
18using llvm::raw_ostream;
1916
2017namespace lld {
2118namespace wasm {
......@@ -35,7 +32,8 @@ void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg);
3532
3633void 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
4038void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig);
4139
......@@ -47,6 +45,10 @@ void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type);
4745
4846void 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
5052void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type);
5153
5254void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import);
......@@ -57,7 +59,8 @@ void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export);
5759
5860std::string toString(llvm::wasm::ValType Type);
5961std::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
6265} // namespace lld
6366